简体   繁体   English

实现阻塞队列的“联合”

[英]Implementation of “union” of blocking queues

Given a collection of BlockingQueue<E> instances, what is the most efficient way of implementing the blocking take() and poll() on that collection as a whole? 给定BlockingQueue<E>实例的集合,在整个集合上实现阻塞take()poll()的最有效方法是什么? Here is the code: 这是代码:

class UnionBlockingQueue<E> implements BlockingQueue<E> {
  private final Collection<BlockingQueue<E>> sources;

  public UnionBlockingQueue(Collection<BlockingQueue<E>> sources) {
    this.sources = sources;
  }


  @Override
  public E take() throws InterruptedException {
    // takes first available E from the sources
  }

  @Override
  public E poll(long timeout, TimeUnit unit) throws InterruptedException {
    // polls first available E from the sources
  }

  // The rest is unsupported/irrelevant/out of scope
  @Override
  public boolean add(E e) {
    throw new UnsupportedOperationException();
  }

  @Override
  public boolean offer(E e) {
    throw new UnsupportedOperationException();
  }
}

I was planning to wrap each source queue in a separate class which would override add/offer methods and trigger this class's notFull and notEmpty conditions just like in the sample usage of Condition , but, being new to Java queues, I thought there might be a better/safer/more efficient approach or a library already in place. 我正打算包装在一个单独的类中的每个源队列这将重写add /报价方法和触发这个类的notFullnotEmpty条件就像在样品的使用条件 ,但是,作为新的Java队列,我想可能有一个更好/更安全/更有效的方法,或者已经建立了一个库。

The simplest way would be to pipe the sub-queues to a SynchronousQueue . 最简单的方法是将子队列传递给SynchronousQueue

public static void main(String[] args) throws InterruptedException {

    // Input queues
    LinkedBlockingDeque<String> q1 = new LinkedBlockingDeque<>();
    LinkedBlockingDeque<String> q2 = new LinkedBlockingDeque<>();
    LinkedBlockingDeque<String> q3 = new LinkedBlockingDeque<>();
    List<LinkedBlockingDeque<String>> qs = Arrays.asList(q1, q2, q3);

    // Output queue
    SynchronousQueue<String> combined = new SynchronousQueue<>(true);

    // Pipe logic
    Executor executor = Executors.newCachedThreadPool(r -> {
        Thread t = new Thread(r, "q pipe");
        t.setDaemon(true);
        return t;
    });

    for (LinkedBlockingDeque<String> q : qs) {
        executor.execute(() -> {
            try {
                while (!Thread.currentThread().isInterrupted()) {
                    combined.put(q.take());
                }
            } catch (InterruptedException e) {
                // done
            }
        });
    }

    // Test
    q1.put("foo");
    q2.put("bar");
    q3.put("baz");

    String e;
    while ((e = combined.poll(100, TimeUnit.MILLISECONDS)) != null) {
        System.out.println(e);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM