代码之家  ›  专栏  ›  技术社区  ›  spongebob

等待所有阻塞队列元素取出后进行处理

  •  1
  • spongebob  · 技术社区  · 8 年前

    在以下场景中,终结器线程必须等待使用者线程处理所有队列元素才能完成执行:

    private final BlockingQueue<Object> queue = new LinkedBlockingQueue<>();
    private final Object queueMonitor = new Object();
    
    // Consumer thread
    while (true) {
        Object element = queue.take();
        consume(element);
        synchronized (queueMonitor) {
            queueMonitor.notifyAll();
        }
    }
    
    // Finalizer thread
    synchronized (queueMonitor) {
        while (!queue.isEmpty()) {
            queueMonitor.wait();
        }
    }
    

    元素随时间添加到队列中。 使用者守护进程线程一直运行,直到JVM终止,此时必须允许它完成对所有排队元素的处理。

    问题:
    false ,因此在 consume() 还没回来因为在等 queueMonitor

    研究:
    理想的解决方案是 peek the queue ,然后在元素被使用后将其移除。

    1 回复  |  直到 8 年前
        1
  •  3
  •   spongebob    8 年前

    一种方法是你可以使用 CountDownLatch 在它上面有finalizer块,用户调用倒计时在 consume()

    基本上不阻塞队列,阻塞任务完成。

    private final BlockingQueue<Object> queue = new LinkedBlockingQueue<>();
    private volatile boolean running = true;
    private final CountDownLatch terminationLatch = new CountDownLatch(1);
    
    // Consumer thread
    while (running || !queue.isEmpty()) {
        Object element = queue.poll(100, TimeUnit.MILLISECONDS);
        if (element == null) continue;
        consume(element);
    }
    terminationLatch.countDown();
    
    // Finalizer thread
    running = false;
    terminationLatch.await();