我正在查看WeakHashMap
的源代码,并偶然发现了这一点:
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方法。
这使我相信这个实现细节是以某种方式确保ReferenceQueue
本身的线程安全(因为GC将从它自己的Thread
修改它)。但是,the documentation for ReferenceQueue
没有提及任何并发问题,并且查看ReferenceQueue
的源代码表明它甚至没有自身同步(它使用内部锁)。
为什么WeakHashMap
在其ReferenceQueue
上进行同步?我每次使用它时都应该ReferenceQueue
进行同步吗?
答案 0 :(得分:6)
如果查看ReferenceQueue
,您会看到它明确支持平台内的线程,因为它声明remove()
方法将阻塞,直到新条目可用。
您在synchronized
中看到的WeakHashMap
是关于确保访问ReferenceQueue
的多个线程正确同步。
您可能会发现此相关的bug at bugs.sun.com很有趣。
要回答您的问题,我认为如果您确保仅由单个线程访问,则不需要ReferenceQueue
的外部同步。我不会使用(并且不能想出一个好的理由)将单个ReferenceQueue
用作来自多个线程的消费者。