java中是否存在线程安全且元素唯一的队列?

wat*_*erg 4 java concurrenthashmap

就像"ConcurrentHashMap"和"ConcurrentLinkedQueue"的混合体.

这是我的要求:
我需要一个异步更新的缓存系统.这意味着我在将每个实体设置为memcache之前将其包装起来.warpper中有一个时间戳,指示其内容何时到期.来自前端的每个请求都将从memcache获取数据,如果warpper显示过期,则会生成更新事件并将其放入concurrentLinkedQueue,然后等待异步更新.
问题是:我不想徒劳地更新一个实体.在将事件添加到队列之前,我希望找到一种方法来确保队列中的同一实体没有事件.

如果我以这些方式这样做,那可以吗?

1,创建一个warpper类,它包含一个hashMap和一个linkedList.它的所有方法都是同步的:

public synchronized boolean add(String key,Object value){
    if(hashMap.containsKey(key)){
        return false;
    }else{
        hashMap.put(key,value);
        return linkedList.offer(value);
    }
}  
Run Code Online (Sandbox Code Playgroud)

我相信这个解决方案会非常慢.
也许它就像Collections.synchronizedMap(new LinkedHashMap()).

2,只需使用concurrentHashMap即可.如果我需要"poll"动作,则从中迭代一个元素.

public Object poll(){
    Collection valueColl = concurrentHashMap.values();
    if(valueColl.isEmpty()){
        retrun null;
    }
    return valueColl.get(0);
}  
Run Code Online (Sandbox Code Playgroud)

行动concurrentHashMap.values().get(0)缓慢与否?

3,查看"ConcurrentHashMap"和"ConcurrentLinkedQueue"的源代码,如果可能的话写一个"ConcurrentUniqueLinkedQueue".
这对我来说现在看起来有点困难.

所以,你们怎么说?

Pet*_*rey 5

我不认为你想丢弃最新的更新.也许你正在使它变得比它需要的更复杂.

public void add(K key, V value) {
    concurrentMap.put(key, value);
    queue.add(key);
}

public V poll() {
    for(K key; (key = queue.take()) != null;) {
        V value = concurrentMap.remove(key);
        if (value != null)
           return value;
        // value will be null if it's a duplicate so ignore and look for more.
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

这将为您提供排队顺序中键的最新值.它不需要任何锁定.