我在看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用作来自多个线程的使用者。

08-27 09:25