Java 我应该在引用队列上同步吗?

Java 我应该在引用队列上同步吗?,java,concurrency,Java,Concurrency,我正在查看WeakHashMap的源代码,无意中发现了以下内容: private final ReferenceQueue<Object> queue = new ReferenceQueue<>(); private void expungeStaleEntries() { for (Object x; (x = queue.poll()) != null; ) { synchronized (queue) { /* sn

我正在查看
WeakHashMap
的源代码,无意中发现了以下内容:

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

private void expungeStaleEntries() {
    for (Object x; (x = queue.poll()) != null; ) {
        synchronized (queue) {
           /* snip */
        }
    }
}
private final ReferenceQueue=new ReferenceQueue();
私人作废删除登记(){
对于(对象x;(x=queue.poll())!=null;){
已同步(队列){
/*剪断*/
}
}
}
为什么此方法在
引用队列
上同步?它本身并不声称是线程安全的:

与大多数集合类一样,该类不同步。A. 同步WeakHashMap可以使用 Collections.synchronizedMap方法

这让我相信,这个实现细节在某种程度上是为了确保
引用队列
本身的线程安全(因为GC将从自己的
线程
对其进行修改)。但是,没有提到任何关于并发性的问题,并且查看
ReferenceQueue
的源代码可以发现它本身甚至没有同步(它使用内部锁)

为什么
WeakHashMap
正在其
ReferenceQueue
上同步?每次使用
ReferenceQueue
时,我是否应该对其进行同步?

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

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

你可能会发现这一点很有趣


为了回答您的问题,我认为如果您确保只有单个线程访问
ReferenceQueue
,则不需要对其进行外部同步。我不会使用(也想不到一个好的理由)将一个
引用队列作为来自多个线程的消费者使用。

+1很好的发现-一个读取方法如何修改映射很有趣。@andersoj啊,那个错误报告说得很清楚。由于在
WeakHashMap
上调用
size
可能会修改基础映射,因此同时调用
size
的用户可能会无意中损坏它。这种行为与大多数(所有?)其他JDK
Map
实现相反,后者允许多个线程毫无问题地读取其内容,因此,他们决定使该类稍微具有线程安全性,以保持与
Map
规范的一致性。@例如,John Vint LinkedHashMap get修改映射,因为它存储访问顺序