【问题标题】:Blocking Queue Vs Classical implementation of Producer Consumer pattern阻塞队列与生产者消费者模式的经典实现
【发布时间】:2013-11-27 20:38:27
【问题描述】:

我知道在实现生产者消费者模式时,我们可以使用BlockingQueue 而不是经典的wait()notify()。我的问题是,哪种实现更有效?在一篇关于阻塞队列的文章中写道——“你不需要使用waitnotify 在生产者和消费者之间进行通信”

阅读更多:http://javarevisited.blogspot.com/2012/02/producer-consumer-design-pattern-with.html#ixzz2lczIZ3Mo" 。这种简单性是以效率为代价的吗??

【问题讨论】:

  • 我会更担心可读性和维护。通过使用简单的数据结构,您将为未来的开发人员节省多少时间?另一方面,如果你推出自己的解决方案,他们会浪费多少时间来弄清楚你为什么不只使用 BlockingQueue?
  • 没想到:P

标签: java multithreading design-patterns


【解决方案1】:

BlockingQueue 会更快,因为它使用等待/通知或同步进行队列访问。所有并发包都使用原子类实现无锁算法。

考虑一个由 100 个元素组成的队列,以及 1000 个想要完成工作的线程。使用同步实现,对于每个元素 999 个线程需要等待,直到 1 个线程选择了它的任务。使用无锁算法,100 个线程同时选择他们的任务,只有其他 900 个需要等待。

【讨论】:

  • 但是 900 个线程仍然在等待,对吧?所以,必须有通知(notify())等待(wait())线程的机制......在我看来它仍然像一个等待通知组合。
  • 正确,但不适用于实际访问。编辑传入。
【解决方案2】:

如果每秒产生/消耗的对象数量少于 100000,那么您将无法看到标准实现或您自己的实现的差异。

否则,您可以使用以下选项来加快代码速度:

  • 使用 ArrayBlockingQueue 代替 LinkedBlockingQueue:无需为每个传输的消息创建包装对象。 ArrayBlockingQueue 的另一个优点是,如果队列已满,生产者线程会被阻塞 - 事实上,如果消费者不快,生产者应该放慢速度,否则我们最终会耗尽内存。

  • 分批发送消息,例如以每组 10 条消息的形式发送。这减少了共享对象上的线程争用。

如果您必须每秒发送数千万条消息,请查看Lmax Disruptor

【讨论】:

  • 这是有道理的。谢谢:)
  • 我可以知道为什么 100000 会有所不同吗?
  • 这可能是 1000000,具体取决于具体机器。对于低级机器,快速同步算法的实现大约需要 1 mks。所以每秒 100000 个事件不会引起争用。
【解决方案3】:

BlockingQueue 只是一个将 wait() 和 notify() 用于这种常见用途的类。一般来说,自己做只是重新发明轮子,只有当你有很多生产者和消费者并且你可以以某种特定于你的代码的方式进行优化时才值得。

【讨论】:

  • 是的。我理解“重新发明轮子”部分。如果我只有一个生产者和一个消费者,哪个会更快阻塞队列或经典的?
  • 从技术上讲,“经典”方式创建的对象更少,并且在实现它时可能存在其他细微差别,但同样,它可以忽略不计,不值得付出额外的努力和出现错误的可能性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-10
  • 2011-01-09
  • 2015-09-25
  • 2012-08-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多