Is there thread safety and unique unique queue in java?

As a hybrid of "ConcurrentHashMap" and "ConcurrentLinkedQueue".

Here are my requirements:
I need an asynchronous updated cache system. This means that I wrap each object before setting it to memcache. The warpper has a timestamp that indicates when its content will expire. Each front-end request was fetching data from memcache, and if the warpper shows an expiration, an update event will be generated and placed in the concurrentLinkedQueue, then waits for updates asynchronously.
The problem is I don't want to update the object more than once wasted. Before adding an event to the queue, I want to find a way to make sure that there is no longer an event for the queue on the same entity.

Is it ok if I do this?

1, create a warpper class, it contains hashMap and associatedList in it. His entire method is synchronized:

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

      

I believe this solution will be extremely slow. Perhaps it looks like Collections.synchronizedMap (new LinkedHashMap ()).

2, just use concurrentHashMap. If I want a "poll" action, the iterator is the element from it.

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

      

Action concurrentHashMap.values().get(0)

is slow or not?

3, looking into the source code for "ConcurrentHashMap" and "ConcurrentLinkedQueue", then write "ConcurrentUniqueLinkedQueue" if possible.
It's a little tricky at this point.

So how would you guys say?

+3


source to share


2 answers


I don't think you want to opt out of the latest updates. Perhaps you are making it more difficult than it should be.

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 a duplicate so ignore and look for more.
    }
    return null;
}

      



This will give you the last value for the key in the queue. It does not require locking.

+5


source


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

}

      



0


source







All Articles