我应该在ReferenceQueue上同步吗?

Jef*_*rey 10 java concurrency

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

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

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

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

与大多数集合类一样,此类不同步.可以使用Collections.synchronizedMap方法构造同步的WeakHashMap.

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

为什么WeakHashMap同步它ReferenceQueue呢?我ReferenceQueue每次使用它时都应该同步吗?

and*_*soj 6

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

synchronized你看到的WeakHashMap就是要确保多线程访问ReferenceQueue进行正确的同步.

您可能会在bugs.sun.com上发现此相关错误.

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