簡體   English   中英

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

[英]Is there a thread-safe and element-unique queue in java?

就像“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);
    }
}  

我相信這個解決方案會非常慢。
也許它就像Collections.synchronizedMap(new LinkedHashMap())。

2,只需使用concurrentHashMap即可。 如果我需要“poll”動作,則從中迭代一個元素。

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

concurrentHashMap.values().get(0)是慢還是沒有?

3,查看“ConcurrentHashMap”和“ConcurrentLinkedQueue”的源代碼,如果可能的話寫一個“ConcurrentUniqueLinkedQueue”。
這對我來說現在看起來有點困難。

所以,你們怎么說?

我不認為你想丟棄最新的更新。 也許你正在使它變得比它需要的更復雜。

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

這將為您提供排隊順序中鍵的最新值。 它不需要任何鎖定。

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

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM