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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With