Java blocking queue containing only unique elements

后端 未结 5 1184
长发绾君心
长发绾君心 2020-12-11 15:45

sort of like a \"blocking set\". How can I implement a blocking queue where adding a member that is already in the set is ignored?

相关标签:
5条回答
  • 2020-12-11 15:55

    You can create a new class that composes a BlockingQueue, a Set, and a lock. When you put() you test against the set while holding a lock that prevents get() from running. When you get() you remove the item from the set so that it can be put() again in the future.

    0 讨论(0)
  • 2020-12-11 15:55

    You can override add and put methods of any implementation of BlockingQueue<T> to check first if the element is already within the queue, e.g.

    @Override
    public boolean add(T elem) {
        if (contains(elem))
            return true;
        return super.add(elem);
    }
    
    0 讨论(0)
  • 2020-12-11 16:01

    I wrote this class to solve a similar problem:

    /**
     * Linked blocking queue with {@link #add(Object)} method, which adds only element, that is not already in the queue.
     */
    public class SetBlockingQueue<T> extends LinkedBlockingQueue<T> {
    
        private Set<T> set = Collections.newSetFromMap(new ConcurrentHashMap<>());
    
        /**
         * Add only element, that is not already enqueued.
         * The method is synchronized, so that the duplicate elements can't get in during race condition.
         * @param t object to put in
         * @return true, if the queue was changed, false otherwise
         */
        @Override
        public synchronized boolean add(T t) {
            if (set.contains(t)) {
                return false;
            } else {
                set.add(t);
                return super.add(t);
            }
        }
    
        /**
         * Takes the element from the queue.
         * Note that no synchronization with {@link #add(Object)} is here, as we don't care about the element staying in the set longer needed.
         * @return taken element
         * @throws InterruptedException
         */
        @Override
        public T take() throws InterruptedException {
            T t = super.take();
            set.remove(t);
            return t;
        }
    }
    
    0 讨论(0)
  • 2020-12-11 16:02
    class BlockingSet extends ArrayBlockingQueue<E> {
       /*Retain all other methods except put*/
       public void put(E o) throws InterruptedException {
          if (!this.contains(o)){
             super.put(o);
          }
       }
    }
    
    0 讨论(0)
  • 2020-12-11 16:05

    A blocking queue implementation backed by a linked hash set for predictable iteration order and constant time addition, removal and contains operations:

    There you go.

    0 讨论(0)
提交回复
热议问题