编程语言
首页 > 编程语言> > java – 如何在并发HashMap中进行Weakrefernce

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