java.lang.reflect.Module.WeakSet is not thread-safe

Peter Levart peter.levart at
Thu Apr 21 16:07:59 UTC 2016


While browsing code in java.lang.reflect.Module (I sometimes do that 
just to see how thinks work ;-) I stumbled on the following nested class:

     private static class WeakSet<E> {
         private final ReadWriteLock lock = new ReentrantReadWriteLock();
         private final Lock readLock = lock.readLock();
         private final Lock writeLock = lock.writeLock();

         private final WeakHashMap<E, Boolean> map = new WeakHashMap<>();

          * Adds the specified element to the set.
         void add(E e) {
             try {
                 map.put(e, Boolean.TRUE);
             } finally {

          * Returns {@code true} if this set contains the specified element.
         boolean contains(E e) {
             try {
                 return map.containsKey(e);
             } finally {

...while this seems OK from 1st look, it is not. WeakHashMap is not 
thread-safe even for seemingly read-only operations. All its operations 
can mutate internal state in a non-thread-safe way. The simplest way to 
fix this is to use a writeLock for containsKey operation too. But such 
structure does not scale well to multiple threads for frequent lookups.

WeakSet is used in Module to keep track of transient read edges, exports 
and uses of services added dynamically to the module. Modification 
operations are not so performance critical, but lookup operations are.

I propose to add a thread-safe WeakPairMap data structure which 
associates a pair of weakly-reachable keys with a strongly-reachable 
value based on ConcurrentHashMap. Such data structure is 
footprint-friendly, since only a single instance exists for a particular 
purpose, totaling 3 instances for the transient structures serving all 
Modules in the system:

So, what do you think?

Regards, Peter

More information about the core-libs-dev mailing list