I have a class to manage lock objects of several features. I've figured out that WeakHashMap should fit my requirement. Here is my code:
public static class FeatureLockManager {
private final Map<Object, WeakKeyLockPair> locks;
private String domain;
public FeatureLockManager(String domain) {
this.domain = domain;
locks = new WeakHashMap<Object, WeakKeyLockPair>();
}
public Lock getLock(Object feature) {
if (locks.get(feature) == null) {
synchronized (locks) {
locks.computeIfAbsent(feature, l -> new WeakKeyLockPair(feature, new ReentrantLock()));
}
}
return locks.get(feature);
}
private static class WeakKeyLockPair implements Lock {
private final Reference<Object> feature;
private final Lock lock;
private WeakKeyLockPair(Object feature, Lock lock) {
this.feature = new WeakReference<Object>(feature);
this.lock = lock;
}
... }
}
However, after making a simple test, I realized that lock object won't be removed after GC.
public static void main(String[] args) throws InterruptedException {
FeatureLockManager test = new FeatureLockManager("test");
Lock lock = test.getLock("add user");
System.out.println(lock.hashCode());
// do thing
System.gc();
Thread.sleep(1000);
Lock lock1 = test.getLock("add user");
System.out.println(lock1.hashCode());
System.out.println(lock1 == lock);
}
Could you please tell me that what's wrong with my implementation? Thank you in advance!
According to the java documentation of the WeakHashMap
Your FeatureLockManager class still has a strong reference to the key element ("add user") of the WeakHashMap.
For more details, check the documentation