【问题标题】:Producer Consumer Blocking Queue生产者消费者阻塞队列
【发布时间】:2013-06-27 00:22:45
【问题描述】:

我有多个生产者和单个消费者的情况。 出于性能原因,我不希望消费者处于任何阻塞状态,但由于可以有更多的生产者,如果队列已满,他们应该“阻塞”。

是否有任何队列为我提供此类行为,或者我如何根据需要修改 ArrayBlockingQueue?

【问题讨论】:

  • ArrayBlockingQueue 不是最终版本,您可以扩展和覆盖其功能。

标签: java queue blocking


【解决方案1】:

对消费者使用非阻塞ArrayBlockingQueue.poll,对生产者使用阻塞ArrayBlockingQueue.put

【讨论】:

  • 这个可能我理解的不正确或者表达的不好,但是查看ArrayBlockingQeueu的源码,poll还是获取了一个锁,也就是说如果还有其他的锁就会排队轮到它了……不是吗?我不希望消费者参与锁定 - 只需从给定索引中获取并通知生产者。我已经用 poll 实现了这个实现,但看起来消费者在某种程度上“挨饿”,因为生产者池(等于队列长度)正在竞争和等待(我假设持有锁)。
  • 嗯,你说你不想阻塞和轮询永远不会阻塞。至于加锁,恐怕你不能做一个无锁的BlockingQueue,因为它需要以某种方式等待/通知
【解决方案2】:

BlockingQueue 的任何实现有什么问题?您的消费者可以调用 peek() poll(),这是非阻塞的,您的生产者可以调用 put(E e),如果队列已满,则阻塞。

更新

如果队列被用于异常密集的任务,那么LMAX's disruptor ring buffer 可能是性能最高的队列结构。

【讨论】:

  • 我需要修改这种锁定的工作方式。我可能无法正确理解这个概念。如果生产者获取了锁并进入“等待”状态......那么消费者想要获取一些元素并在队列上执行“锁定” - 会发生什么?生产者没有锁吗?
  • 在调用poll() 的过程中,消费者线程有一种(很小的)可能性会切换上下文,并且在持有锁的同时阻塞其他消费者,但这可能是短暂的.除非您处于 significant 之下(以每秒数十万次队列访问的顺序),否则我不希望它会给您带来问题。如果您正在做一些密集的事情,那么看看 LMAX 的颠覆者:lmax-exchange.github.io/disruptor
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-09
  • 2015-09-25
  • 1970-01-01
  • 2014-10-21
  • 2014-02-20
  • 1970-01-01
  • 2021-09-10
相关资源
最近更新 更多