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){
增加(价值);
}
}
}
返回值;
}
}
谢谢,祝你今天愉快