我在看WeakHashMap
的源代码,偶然发现了这一点:
private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
private void expungeStaleEntries() {
for (Object x; (x = queue.poll()) != null; ) {
synchronized (queue) {
/* snip */
}
}
}
为什么此方法在
ReferenceQueue
上同步? WeakHashMap
本身并不声称是线程安全的:这使我相信,此实现细节将以某种方式确保
ReferenceQueue
本身的线程安全(因为GC将从其自己的Thread
对其进行修改)。但是,the documentation for ReferenceQueue
并没有提及任何有关并发性的问题,并且查看ReferenceQueue
的源代码后发现它甚至没有自身同步(它使用内部锁)。为什么
WeakHashMap
在其ReferenceQueue
上同步?我应该在每次使用ReferenceQueue
时进行同步吗? 最佳答案
如果查看 ReferenceQueue
,您会看到它明确支持平台内的线程,因为它指出remove()
方法将阻塞,直到有新条目可用为止。
您在synchronized
中看到的WeakHashMap
与确保访问ReferenceQueue
的多个线程正确同步有关。
您可能会发现与此相关的bug at bugs.sun.com很有趣。
为了回答您的问题,我认为如果您确保仅由单个线程访问ReferenceQueue
,则不需要外部同步。我不会使用(也没有想到充分的理由)将单个ReferenceQueue
用作来自多个线程的使用者。