java - 我应该在 ReferenceQueue 上同步吗?

标签 java concurrency

我在查看 WeakHashMap 的源代码时偶然发现了这个:

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

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

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

Like most collection classes, this class is not synchronized. A synchronized WeakHashMap may be constructed using the Collections.synchronizedMap method.

这让我相信这个实现细节是为了以某种方式确保 ReferenceQueue 本身的线程安全(因为 GC 将从它自己的 Thread 修改它>).然而,the documentation for ReferenceQueue没有提及任何并发性问题,查看 ReferenceQueue 的源代码会发现它甚至不同步自身(它使用内部锁)。

为什么 WeakHashMap 在其 ReferenceQueue 上同步?每次使用时都应该在 ReferenceQueue 上同步吗?

最佳答案

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

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

您可能会发现这个相关的 bug at bugs.sun.com有趣。

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

关于java - 我应该在 ReferenceQueue 上同步吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10591851/

相关文章:

java - 在 Guice 中注入(inject)通用工厂

java - 三角数学用BigDecimal没用?

scala - 在Scala中逐行并发读取和处理文件

concurrency - 什么是 Swift 相当于 Objective-C 的 "@synchronized"?

c++ - 如何在多个线程之间进行同步。只有一个在写

c++ - 从另一个对象指向线程对象 : dangerous?

java - 尝试打印数组

java - 如何让paintComponent方法出现在屏幕上

java - Android:将变量传递给非 Activity 类

java.io.InputStreamReader.ready() 阻止执行