11

ソースコードを調べていて、WeakHashMapこれに出くわしました:

private final ReferenceQueue<Object> queue = new ReferenceQueue<>();

private void expungeStaleEntries() {
    for (Object x; (x = queue.poll()) != null; ) {
        synchronized (queue) {
           /* snip */
        }
    }
}

このメソッドが で同期するのはなぜReferenceQueueですか? WeakHashMapそれ自体は、スレッドセーフであるとは主張していません。

ほとんどのコレクション クラスと同様に、このクラスは同期されません。Collections.synchronizedMap メソッドを使用して、同期された WeakHashMap を構築できます。

これにより、この実装の詳細は、どういうわけか、それ自体のスレッドセーフを確保するためのものであると私は信じるようになりReferenceQueueました (GC がそれ自体からそれを変更するためThread)。ただし、のドキュメントでReferenceQueueは、同時実行に関する問題については何も言及されておらず、ソース コードを調べてみると、ReferenceQueueそれ自体で同期さえしていない (内部ロックを使用している) ことがわかります。

WeakHashMapで同期するのはなぜReferenceQueueですか? ReferenceQueue使用するたびに同期する必要がありますか?

4

1 に答える 1

6

見てReferenceQueueみると、プラットフォーム内のスレッド化を明示的にサポートしていることがわかります。これremove()は、新しいエントリが利用可能になるまでメソッドがブロックされることが示されているためです。

synchronizedに表示されているのは、にWeakHashMapアクセスする複数のスレッドReferenceQueueが適切に同期されていることを確認することです。

bugs.sun.com にあるこの関連するバグが興味深いと思われるかもしれません。

あなたの質問に答えるReferenceQueueために、単一のスレッドによってのみアクセスされることが保証されている場合、の外部同期は必要ないと思います。ReferenceQueue複数のスレッドからのコンシューマーとして単一を使用することはありません (そして正当な理由は考えられません) 。

于 2012-05-15T14:31:06.740 に答える