多生产者单个消费者队列没有专用的消费者线

时间:2015-06-18 21:30:07

标签: java multithreading

我正在编写一个异步应用程序,它将元素提交到工作队列进行处理。要求是:

  • 没有后台线程侦听队列。任何向队列提交元素的线程都可能负责使用队列。
  • 可以有多个并发生成器,但只有一个线程可以成为活动消费者。
  • 如果线程A提交了一个元素但是线程B正在主动消耗队列,则线程A应该立即返回。没等了。

以下是我尝试做的一个例子:

final Queue<T> queue = new ConcurrentLinkedQueue<>();
final AtomicBoolean processing = new AtomicBoolean();

void offer(T t) {
    queue.offer(t);

    for (;;) {
        if (processing.compareAndSet(false, true)) {
            try {
                for (;;) {
                    T t = queue.poll();
                    if (t == null) {
                        break;
                    }
                    // process t
                }
            } finally {
                processing.set(false);
            }

            // see if another thread submitted an element but didn't process it
            // if not, we can break
            if (queue.isEmpty()) {
                break;
            }
        } else {
            // losers should exit
            break;
        }
    }
}

认为我的代码有效,但这个问题听起来相当标准,所以我想知道是否有任何教科书解决方案或至少是一个通用名称。到目前为止,我只找到需要工作线程监听队列的算法。

1 个答案:

答案 0 :(得分:1)

您的代码是正确的,但问题不被视为标准:通常,拥有后台线程并不是那么昂贵,因为:

  1. 生产者没有有限时间保证。某些生产者可能在消费模式下长时间工作。

  2. 复制制作人的代码。

  3. 在任何情况下,您的问题标题(MPSC without dedicated consumer thread)都能很好地描述问题。为了解决这个问题,您可以将trylock/unlock方法与任何MPSC实现相结合,而无需通知机制。 MPSC的唯一额外要求是并发 queue.isEmpty()方法,但通常不是问题。