クラスのすべてのメソッドを個別に同期しても、それらのメソッドの集約 ( group で呼び出し) はスレッドセーフになりません。を同期ブロックでラップすることによりIterator、反復子の特定のインスタンスが、複数のスレッドによる他の呼び出しに散在して呼び出される個々のメソッドを持つことから保護されます。
一度呼び出す.add()と安全であり、論理ステートメントを完了するために複数回呼び出す必要がある場合、他のすべての呼び出しをブロックしない限り、呼び出し.add()の間に他の誰かが何かを追加したり削除したりしていないという保証はありません(またはコレクションを表す変数を使用します。.add().add()synchronizing
はIterator、コレクションの個々のメソッドに対して複数の呼び出しを行います。synchronized単一transactionの並べ替えとして実行するには、それらをすべて単一のブロックにラップする必要があります。あなたの実装のソースコードを調べると、 Iterator私が何を意味するかがわかります。これは、基になる実装に対して複数の個別の呼び出しを行うためのソース コードですList。そのため、それらはすべて、決定論的であるために同じスレッドによって中断されずに実行される必要があります。
@Override
public Iterator<A> iterator() {
if (tail == null)
return emptyIterator();
return new Iterator<A>() {
List<A> elems = List.this;
public boolean hasNext() {
return elems.tail != null;
}
public A next() {
if (elems.tail == null)
throw new NoSuchElementException();
A result = elems.head;
elems = elems.tail;
return result;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
のソースAbstractList.iterator()は、複数の呼び出しを行うさらに複雑なロジックを示しています。
より良いラッパーは、それらをImmutableコレクションにラップすることです。そうすれば、呼び出し間で基になるコレクションを変更できないことを保証できます。