2

Java doc では、同期されたコレクションを繰り返して手動で再度同期する必要があると書かれています。何故ですか?返されたコレクションは既に同期されているためです。なぜこのようになっているのかよくわかりません。ありがとうございました。

 Collection c = Collections.synchronizedCollection(myCollection);
      ...
    synchronized(c) {
        Iterator i = c.iterator(); // Must be in the synchronized block
        while (i.hasNext())
          foo(i.next());
   }
4

3 に答える 3

3

個々のメソッドのみが同期されます。コードの他の部分が、反復子で行っている呼び出しの間にこれらのメソッドを呼び出すことが許可されている場合、リストの整合性が失われ、この場合、同期は無意味になります。

リストがラップされている同期ブロックを必要とせずに使用できるメソッドがいくつかある可能性がありますsynchronizedCollection(リスト内の要素の数をチェックするなど)。メソッドの場合、両方のメソッド呼び出しの周りに同期ブロックが必要であり、これらの呼び出しの間でリストの状態に他のものが触れないようにする必要があります。

于 2013-02-16T22:11:50.690 に答える
3

その理由は、反復操作がリストのロックを維持できないためです。たとえば、i.hasNext()は をチェックする間だけリストをロックしますが、実際に を呼び出す前にリストが再びhasNext()変更される可能性があります。next()

したがって、代わりに、各操作を個別に行うのではなく、反復全体を同期させるために、自分でリストをロックする必要があります。

于 2013-02-16T22:11:55.657 に答える
0

iteratorループが2つの異なるスレッドで実行されていると想像してください。i.next().remove()一方のスレッドが同じスレッドでループしているときに一方のスレッドが呼び出すことは完全に合法でlistあり、これによりリスト内のデータの一貫性が損なわれる可能性があります。

于 2013-02-16T22:17:43.500 に答える