私はWeakHashMap
のソースコードを見て取り、これに出くわした:ReferenceQueueで同期する必要がありますか?
private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
private void expungeStaleEntries() {
for (Object x; (x = queue.poll()) != null;) {
synchronized (queue) {
/* snip */
}
}
}
この方法はReferenceQueue
に同期しないのはなぜ? WeakHashMap
自体は、スレッドセーフではありません:
ほとんどのコレクションクラスと同様、このクラスは同期されていません。 WeakHashMapを同期させるには、 Collections.synchronizedMapメソッドを使用します。この実装の詳細は、(GCが
Thread
独自のからそれを修正することになるので)、何とか、ReferenceQueue
自体のスレッドの安全性を確保することであると信じている私を導い
。しかし、the documentation for ReferenceQueue
には同時性に関する懸念事項は何も言及されておらず、ReferenceQueue
のソースコードを見ても、それ自体は同期していない(内部ロックを使用している)ことさえある。
なぜWeakHashMap
はReferenceQueue
で同期していますか?私はそれを使用するたびにReferenceQueue
で同期する必要がありますか?
+1ニースfind - 読み込み方法が地図をどのように変更するか興味深い。 –
@andersojああ、そのバグレポートはそれを明確にしています。 'WeakHashMap'で' size'を呼び出すと根底にあるマップが変更される可能性があるので、 'size'を同時に呼び出すユーザーは誤ってそれを壊す可能性があります。この動作は、複数のスレッドが問題なくコンテンツを読むことを可能にするほとんどの(すべての)JDKの 'Map'実装に反しているので、クラスをスレッドセーフなものにして' Map'仕様である。 – Jeffrey
@John VintたとえばLinkedHashMap getはacessの注文を格納するためマップを変更します – gstackoverflow