在我的程序中,我有一个场景,其中多个线程将在单个 Map 上操作(放置和获取)。就像线程一样,使用在映射中放置一个键/值,同时另一个线程从映射中检索相同或不同键的键/值。现在,如果我让我的地图同步,那么这将是一个很大的性能问题,所以我决定转向 ConcurrentHashMap。在这种情况下,我有另一个复杂性,在一段时间后(我的应用程序不知道),我的应用程序中不需要很少的键/值对,所以我需要删除相同的(垃圾收集)以释放内存。尽管我的程序不知道不需要哪些键/值,但我认为使用弱引用。因此,在一段时间后,如果 key(String) 不可访问,它将自动被垃圾收集。我知道在 WeakhashMap 中执行相同操作的过程,但不知道在 ConcurrentHashMap 中执行此操作的过程。那么,谁能告诉我如何在 ConcurrentHashMap 中进行弱引用。或者还有其他方法可以实现上述场景吗?
问问题
1186 次
1 回答
3
查看WeakHashMap
代码,似乎没有直接的方法可以做到这一点,但下面这种形式的东西应该可以工作:(这段代码实际上没有经过测试,但我认为它至少在正确的路径上,它也只实现了 put和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
,或什至. 然而,在当前场景中的问题是,在块内进行实际轮询,因此清理可能会减慢您的速度(但是,如果队列为空,它将不会锁定,因此它不会撤消所有的速度改进工作是正在做)。expungeStaleEntries()
put()
get()
size()
ReferenceQueue.poll()
synchronized
ConcurrentHashMap
于 2013-08-19T20:56:54.787 回答