4

就像“ConcurrentHashMap”和“ConcurrentLinkedQueue”的混合体。

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

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

1、创建一个warpper Class,里面包含一个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);
    }
}  

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

2、只需使用一个concurrentHashMap。如果我需要“轮询”操作,请从中迭代一个元素。

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

动作concurrentHashMap.values().get(0)慢不慢?

3、查看“ConcurrentHashMap”和“ConcurrentLinkedQueue”的源代码,如果可能的话,写一个“ConcurrentUniqueLinkedQueue”。
目前这对我来说有点难。

那么,你们会怎么说呢?

4

2 回答 2

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;
}

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

于 2013-02-01T09:16:33.373 回答
0
import java.util.LinkedHashSet;
import java.util.Queue;
import java.util.concurrent.locks.ReentrantLock;

public class ConcurrentSetQueue<E> extends LinkedHashSet<E> implements Queue<E> {

    /**
     * 
     */
    private static final long serialVersionUID = 7906542722835397462L;

    final java.util.concurrent.locks.ReentrantLock lock = new ReentrantLock();

    public E remove() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            E next = iterator().next();
            remove(next);
            return next;
        } finally {
            lock.unlock();
        }
    }

    @Override
    public E element() {
        return iterator().next();
    }

    @Override
    public boolean offer(E arg0) {
        return add(arg0);
    }

    @Override
    public E peek() {
        return element();
    }

    @Override
    public E poll() {
        return remove();
    }

}
于 2017-09-12T22:42:17.217 回答