Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I synchronize on a ReferenceQueue?

I was taking a look at the source code for WeakHashMap and stumbled across this:

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

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

Why does this method synchronize on the ReferenceQueue? WeakHashMap itself does not make claims to be thread safe:

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

Which led me to believe that this implementation detail is to, somehow, ensure the thread safety of the ReferenceQueue itself (since the GC will be modifying it from its own Thread). However, the documentation for ReferenceQueue does not mention anything about any concurrency concerns, and taking a look at the source code for ReferenceQueue reveals that it doesn't even synchronize on itself (it uses an internal lock).

Why is WeakHashMap synchronizing on its ReferenceQueue? Should I synchronize on a ReferenceQueue every time I use it?

like image 215
Jeffrey Avatar asked May 14 '12 22:05

Jeffrey


1 Answers

If you look at ReferenceQueue you will see that it explicitly supports threading inside the platform, because it states that the remove() method will block until a new entry is available.

The synchronized you see in WeakHashMap is about ensuring that multiple threads accessing a ReferenceQueue are properly synchronized.

You might find this related bug at bugs.sun.com interesting.

To answer your question, I think external synchronization of the ReferenceQueue is not required if you ensure it is only accessed by a single thread. I would not use (and can't think of a good reason) to use a single ReferenceQueue as a consumer from multiple threads.

like image 180
andersoj Avatar answered Oct 21 '22 03:10

andersoj