How to make Weakrefernce in a parallel HashMap

In my program, I have a scenario in which Mutiple Thread will work (put and receive) on one card. Like Thread a, use put / key on the card, and at the same time, another thread is extracting the key / value from the card for the same or different key. Now, if I synchronize my card, then this will be a big performance problem, so I decided to switch to ConcurrentHashMap. During this scenario, I have one more difficulty, which after a certain period of time (not known to my application) in my application does not require several key / value pairs, so I need to delete the same (Garbage Collection) in free memory. Although my program has no idea that key / values ​​are not needed, I thought of using a weak solution. Thus, after the ceratin period, if the key (String) is not available, garbage will be automatically collected. I know that a process should do the same in WeakhashMap, but does not know how to do it in ConcurrentHashMap. So can anyone tell me how to make a weak referent in ConcurrentHashMap. Or is there another way to achieve the above scenario?

+4
source share
1 answer

Looking through the WeakHashMap code, it seems that there is no direct way to do this, but something from this following form should work: (This code has not actually been tested, but I think it is at least on the right track, it also implements only put and get, other operations can also be implemented)

 public class MyMap<K, V> { private class MyKey<K> extends WeakReference<K> { private final int hashCode; private MyKey(K k, ReferenceQueue<K> q) { super(k, q); hash = k.hashCode(); } private MyKey(K k) { super(k); hash = k.hashCode(); } @Override public int hashCode() { return hashCode; } @Override public boolean equals(Object o) { if (!(o instanceof MyKey)) { return false; } K otherKey = ((MyKey<K>) o).get(); K myKey = get(); if (otherKey != null && key != null) { return otherKey.equals(myKey); } return this == o; } } private final Map<MyKey<K>, V> map = new ConcurrentHashMap<MyKey<K>, V>(); private final ReferenceQueue<K> queue = new ReferenceQueue<K>(); public V put(K key, V val) { expungeStaleEntries(); return map.put(new MyKey<K>(key, queue), val); } public V get(K key) { expungeStaleEntries(); return map.get(new MyKey<K>(key)); } private void expungeStaleEntries() { MyKey<K> key = null; while ((key = (MyKey<K>) queue.poll()) != null) { map.remove(key); } } } 

The potential incorrectness of the above code aside, another caveat is that WeakHashMap works by calling its own expungeStaleEntries() method every time you call things like put() , get() or even size() . However, the problem with this in the current scenario is that ReferenceQueue.poll() does the actual polling inside the synchronized block, so cleaning can slow down (however, it will not block if the queue is empty, so it doesn’t cancel all work on improving the speed ConcurrentHashMap ).

+3
source

Source: https://habr.com/ru/post/1497869/


All Articles