Collection フレームワークで、外部同期が内部同期 (Vector、HashTable など) よりも速いのはなぜですか? どちらも同じメカニズムを使用しているのに?
内部同期と外部同期の正確な意味と、それらの違いは何ですか?
誰かが例を挙げて説明できると本当に助かります。
Collection フレームワークで、外部同期が内部同期 (Vector、HashTable など) よりも速いのはなぜですか? どちらも同じメカニズムを使用しているのに?
内部同期と外部同期の正確な意味と、それらの違いは何ですか?
誰かが例を挙げて説明できると本当に助かります。
内部同期と外部同期の正確な意味と、それらの違いは何ですか?
外部同期とは、呼び出し元 (ユーザー) がsynchronized
キーワードまたは他のロックを使用して、別のクラスが複数のスレッドによってアクセスされないように保護する場合です。通常、問題のクラス自体が同期されていないSimpleDateFormat
場合に使用されます。これが代表的な例です。また、スレッド間のシグナル伝達が必要な場合にも使用できます。同時コレクションを処理する場合でも使用できます。
外部同期が内部同期(Vector、HashTableなど)よりも速いのはなぜですか? どちらも同じメカニズムを使用しているのに?
外部同期は必ずしも高速ではありません。通常、クラスは、呼び出し元がすべてのメソッド呼び出しをsynchronized
ブロックにラップするのではなく、コードのクリティカル セクションを同期する必要がある時期を正確に判断できます。
andを使用せず、代わりにorメソッドを使用するという一般的な推奨事項について話している場合、これはandが古い/古いクラスと見なされるためです。ラップされたorは、より良い解決策と見なされます。Vector
HashTable
Collections.synchronizedList(...)
synchronizedMap(...)
Vector
HashTable
ArrayList
HashMap
@Chris が指摘したように、クラスに多数の変更を次々に加える必要がある場合、外部同期の方が高速になることがあります。外部で一度ロックしてからクラスに複数の変更を実行することで、各変更を内部でロックするよりもうまく機能します。複数のロック呼び出しが連続して行われるよりも、単一のロックの方が高速です。
誰かが例を挙げて説明できると本当に助かります。
の代わりにVector
、人々は通常、ラップArrayList
された方がパフォーマンスが優れていると推奨します。これにより、同期されていないArrayList
クラスが、外部で同期されるラッパー クラスにラップされます。
List<Foo> list = Collections.synchronizedList(new ArrayList<Foo>());
内部と外部の一般的な観点から、複数のスレッドが同時に使用できるようにする次のクラスを検討してください。
public class Foo {
private int count;
public void addToCount() {
count++;
log.info("count increased to " + count);
}
}
外部同期を使用して、すべての呼び出しをブロックにラップできaddToCount()
ますsynchronized
。
synchronized (foo) {
foo.addToCount();
}
または、クラス自体が内部同期を使用して、ロックを行うことができます。これは、ロガー クラスがロックの一部である必要がないため、パフォーマンスが向上します。
public void addToCount() {
int val;
synchronized (this) {
val = ++count;
}
// this log call should not be synchronized since it does IO
log.info("count increased to " + val);
}
もちろん、この場合、Foo
クラスは本当に an を使用し、AtomicInteger
内部で独自の再入を処理する必要があります。
private final AtomicInteger count = new AtomicInteger(0);
public void addToCount() {
int val = count.incrementAndGet()
log.info("count increased to " + val);
}