java – 如何在并发HashMap中进行Weakrefernce
作者:互联网
在我的程序中,我有一个场景,Mutiple Thread将在一个Map上运行(put和get).与线程一样,使用在地图中放置一个键/值,同时另一个线程从地图中检索相同或不同键的键/值.现在,如果我使我的地图同步,那么它将是一个很大的性能问题,所以我决定转移到ConcurrentHashMap.在这种情况下,我有另一个复杂性,在一段时间后(我的应用程序不知道)我的应用程序中不需要很少的键/值对,所以我需要删除相同的(垃圾收集)来释放内存.虽然我的程序不知道不需要哪些键/值,但我想使用weakrefernce.因此,在ceratin一段时间后如果密钥(String)不可达,它将自动被垃圾收集.我知道在WeakhashMap中执行相同操作的过程,但不知道在ConcurrentHashMap中执行此过程的过程.那么,任何人都可以告诉我如何在ConcurrentHashMap中进行弱化.或者还有其他方法来实现上述场景吗?
解决方法:
查看WeakHashMap代码似乎没有直接的方法来执行此操作,但以下形式的某些内容应该有效:(此代码实际上尚未经过测试,但我认为它至少在正确的路径上,也只是实现put and get,其他操作同样可以实现)
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);
}
}
}
除了上述代码的潜在不正确之外,另一个警告是WeakHashMap每次调用put(),get()或者size()之类的东西时都会通过调用自己的expungeStaleEntries()方法来工作.然而,当前场景中的问题是ReferenceQueue.poll()在同步块内部进行实际轮询,因此清理可能会减慢速度(但是如果队列为空则它不会锁定,因此它不会撤消全部ConcurrentHashMap正在进行速度提升工作).
标签:java,collections,garbage-collection,weak-references,java-util-concurrent 来源: https://codeday.me/bug/20190629/1325787.html