Java WeakMultiMap性能建议

Java WeakMultiMap性能建议,java,multithreading,weak-references,Java,Multithreading,Weak References,我制作了一个弱多重映射,它将删除不再引用的值。 我正在努力提高的put和get性能,并尽量减少锁定时间。 get和put函数都应该是线程安全的 没有目标延迟时间, 我想要一些建议,如果我错过了一些可以提高性能的东西 import java.lang.ref.ReferenceQueue; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Loc

我制作了一个弱多重映射,它将删除不再引用的值。
我正在努力提高
的put
get
性能,并尽量减少锁定时间。
get
put
函数都应该是线程安全的

没有目标延迟时间,
我想要一些建议,如果我错过了一些可以提高性能的东西


import java.lang.ref.ReferenceQueue;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer;

/**
 * A key <K> to {@link ArrayList} of type <T> map.
 * Each element in the {@link Set} is Weak Referenced,
 * when a key's {@link ArrayList} is empty the entry is removed.
 * @param <K> - Key type
 * @param <V> - Value type
 */
public class WeakMultiMap<K, V> {

    // Reference queue to detect which objects are collected by GC
    private ReferenceQueue<V> _garbageQueue;
    private Lock _staleLock;

    private Map<K, Collection<WeakLink<K, V>>> _linkHashMap;
    private ReadWriteLock _linkMapModifyLock;

    private Consumer<K> _onLinkRemove;

    public WeakMultiMap() {
        this(null);
    }

    public WeakMultiMap(Consumer<K> onLinkRemove) {
        _onLinkRemove = onLinkRemove;
        _linkHashMap = new ConcurrentHashMap<>();
        _garbageQueue = new ReferenceQueue<>();

        _linkMapModifyLock = new ReentrantReadWriteLock();
        _staleLock = new ReentrantLock();
    }

    /**
     * Remove links which has been GCed.
     */
    private void expungeStaleEntries() {
        // Try acquiring the lock,
        // if someone else already cleaning the stale links.
        if(_staleLock.tryLock()) {
            try {
                for (Object o; (o = _garbageQueue.poll()) != null; ) {
                    @SuppressWarnings("unchecked")
                    K link = ((WeakLink<K, V>)o).getLink();
                    Collection<WeakLink<K, V>> linkedObjects = _linkHashMap.get(link);
                    linkedObjects.remove(o);

                    if (linkedObjects.isEmpty()) {
                        // Don't allow adding links concurrently
                        _linkMapModifyLock.writeLock().lock();
                        try {
                            // Recheck the linked objects are still empty,
                            // a link could have been concurrently added.
                            if (linkedObjects.isEmpty()) {
                                _linkHashMap.remove(link);

                                // Notify the link has been removed
                                if(_onLinkRemove != null) {
                                    _onLinkRemove.accept(link);
                                }
                            }
                        } finally {
                            _linkMapModifyLock.writeLock().unlock();
                        }
                    }
                }
            } finally {
                _staleLock.unlock();
            }
        }
    }

    public void put(K key, V value){
        // Don't allow removing links concurrently
        _linkMapModifyLock.readLock().lock();
        try {
            // Create a set in case no set exists
            _linkHashMap.computeIfAbsent(key, (k) -> ConcurrentHashMap.newKeySet());
            Collection<WeakLink<K, V>> objects = _linkHashMap.get(key);
            objects.add(new WeakLink<>(key, value, _garbageQueue));
        } finally {
            _linkMapModifyLock.readLock().unlock();
        }

        // Cleanup links which are pointing to null
        expungeStaleEntries();
    }

    public Collection<V> get(K key){
        Collection<V> values;

        Collection<WeakLink<K, V>> links = _linkHashMap.get(key);
        if(links == null || links.isEmpty()) {
            values = new ArrayList<>(0);
        }else {
            // Make a strong reference to the values.
            // Insert into a set to ensure unique values.
            values = new HashSet<>(links.size());
            for (WeakLink<K, V> wl : links) {
                V value = wl.get();
                if (value != null) {
                    values.add(value);
                }
            }
        }

        return values;
    }
}

导入java.lang.ref.ReferenceQueue;
导入java.util.*;
导入java.util.concurrent.ConcurrentHashMap;
导入java.util.concurrent.locks.Lock;
导入java.util.concurrent.locks.ReadWriteLock;
导入java.util.concurrent.locks.ReentrantLock;
导入java.util.concurrent.locks.ReentrantReadWriteLock;
导入java.util.function.Consumer;
/**
*map类型的{@link ArrayList}的键。
*{@link Set}中的每个元素都是弱引用的,
*当键的{@link ArrayList}为空时,该项将被删除。
*@param-密钥类型
*@param-值类型
*/
公共类WeakMultiMap{
//用于检测GC收集的对象的引用队列
私人参考队列(garbageQueue);;
私用锁(staleLock);;
私有地图linkHashMap;
私有读写锁_linkMapModifyLock;
私人消费者在线删除;
公共弱点多重映射(){
这个(空);
}
public WeakMultiMap(仅限消费者链接删除){
_onLinkRemove=onLinkRemove;
_linkHashMap=新的ConcurrentHashMap();
_garbageQueue=新引用队列();
_linkMapModifyLock=新的ReentrantReadWriteLock();
_staleLock=新的ReentrantLock();
}
/**
*删除已GCed的链接。
*/
私人作废删除登记(){
//尝试获取锁,
//如果其他人已经在清理过时的链接。
if(_staleLock.tryLock()){
试一试{
for(对象o;(o=\u garbageQueue.poll())!=null;){
@抑制警告(“未选中”)
K link=((弱)o.getLink();
集合linkedObjects=\u linkHashMap.get(链接);
链接对象。移除(o);
if(linkedObjects.isEmpty()){
//不允许同时添加链接
_linkMapModifyLock.writeLock().lock();
试一试{
//重新检查链接对象是否仍然为空,
//可以同时添加一个链接。
if(linkedObjects.isEmpty()){
_linkHashMap.remove(link);
//通知链接已删除
如果(_onLinkRemove!=null){
_onLinkRemove.accept(链接);
}
}
}最后{
_linkMapModifyLock.writeLock().unlock();
}
}
}
}最后{
_staleLock.unlock();
}
}
}
公开作废认沽权(K键,V值){
//不允许同时删除链接
_linkMapModifyLock.readLock().lock();
试一试{
//如果不存在集合,请创建集合
_linkHashMap.computeIfAbsent(key,(k)->ConcurrentHashMap.newKeySet());
集合对象=_linkHashMap.get(键);
添加(新的弱点(键,值,_garbageQueue));
}最后{
_linkMapModifyLock.readLock().unlock();
}
//清除指向null的链接
删除estalentries();
}
公共集合获取(K键){
收集值;
集合链接=_linkHashMap.get(键);
if(links==null | | links.isEmpty()){
值=新的ArrayList(0);
}否则{
//强烈引用这些值。
//插入到集合中以确保值唯一。
values=新的HashSet(links.size());
for(弱链接:链接){
V值=wl.get();
if(值!=null){
增加(价值);
}
}
}
返回值;
}
}
谢谢,祝你今天愉快