11

我正在查看源代码WeakHashMap并偶然发现:

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

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

为什么这个方法在 上同步ReferenceQueueWeakHashMap本身并没有声称是线程安全的:

像大多数集合类一样,这个类是不同步的。可以使用 Collections.synchronizedMap 方法构造同步的 WeakHashMap。

这让我相信这个实现细节是为了以某种方式确保ReferenceQueue自身的线程安全(因为 GC 将从它自己的 GC 中修改它Thread)。但是,文档ReferenceQueue没有提到任何关于并发问题的内容,查看源代码ReferenceQueue会发现它甚至不同步自身(它使用内部锁)。

为什么WeakHashMap在其上进行同步ReferenceQueueReferenceQueue我应该在每次使用时同步吗?

4

1 回答 1

6

如果您看一下,ReferenceQueue您会发现它明确支持平台内部的线程,因为它声明该remove()方法将阻塞,直到有新条目可用。

synchronized您看到的是WeakHashMap关于确保访问 aReferenceQueue的多个线程正确同步。

您可能会在 bugs.sun.com 上发现这个相关的错误很有趣。

要回答您的问题,我认为ReferenceQueue如果您确保它仅由单个线程访问,则不需要外部同步。我不会使用(也想不出一个很好的理由)将单个ReferenceQueue用作来自多个线程的消费者。

于 2012-05-15T14:31:06.740 回答