36 | 生产者-消费者模式:用流水线思想提高效率
王宝令
该思维导图由 AI 生成,仅供参考
前面我们在《34 | Worker Thread 模式:如何避免重复创建线程?》中讲到,Worker Thread 模式类比的是工厂里车间工人的工作模式。但其实在现实世界,工厂里还有一种流水线的工作模式,类比到编程领域,就是生产者 - 消费者模式。
生产者 - 消费者模式在编程领域的应用也非常广泛,前面我们曾经提到,Java 线程池本质上就是用生产者 - 消费者模式实现的,所以每当使用线程池的时候,其实就是在应用生产者 - 消费者模式。
当然,除了在线程池中的应用,为了提升性能,并发编程领域很多地方也都用到了生产者 - 消费者模式,例如 Log4j2 中异步 Appender 内部也用到了生产者 - 消费者模式。所以今天我们就来深入地聊聊生产者 - 消费者模式,看看它具体有哪些优点,以及如何提升系统的性能。
生产者 - 消费者模式的优点
生产者 - 消费者模式的核心是一个任务队列,生产者线程生产任务,并将任务添加到任务队列中,而消费者线程从任务队列中获取任务并执行。下面是生产者 - 消费者模式的一个示意图,你可以结合它来理解。
生产者 - 消费者模式示意图
从架构设计的角度来看,生产者 - 消费者模式有一个很重要的优点,就是解耦。解耦对于大型系统的设计非常重要,而解耦的一个关键就是组件之间的依赖关系和通信方式必须受限。在生产者 - 消费者模式中,生产者和消费者没有任何依赖关系,它们彼此之间的通信只能通过任务队列,所以生产者 - 消费者模式是一个不错的解耦方案。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
生产者-消费者模式在并发编程中的应用是一种重要的技术实践。本文深入探讨了该模式的优点和在性能优化方面的应用。通过示例代码展示了如何利用生产者-消费者模式实现批量执行SQL和异步刷盘的应用场景。文章还提到了Java语言提供的线程池本身就是一种生产者-消费者模式的实现,但在某些场景下仍需要自行实现。此外,生产者-消费者模式在分布式计算中也有广泛应用,可以借助分布式消息队列来实现。在课后思考部分,作者提出了关于优雅终止写日志线程的问题,鼓励读者分享自己的想法和思考过程。整体而言,本文为读者提供了丰富的实践经验和技术指导,对于想要深入了解生产者-消费者模式的读者具有很高的参考价值。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 并发编程实战》,新⼈⾸单¥59
《Java 并发编程实战》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(42)
- 最新
- 精选
- 锦在应用系统中,日志系统一般都是最后关闭的吧,因为它要为其他系统关闭提供写日志服务。所以日志系统关闭时需要把队列中所有日志都消费掉才能关闭。 可能需要在关闭日志系统时投入一个毒丸,表示没有新的日志写入。线程池在消费到毒丸时知道没有日志写入,将所有的日志刷盘,break循环体。
作者回复: 👍
2019-05-21138 - PK時頭髮不亂极客时间有好多课程, 我觉得王老师的干货是最实际最可用的, 必须要赞一个。
作者回复: 感谢感谢,有钱难买合适:)
2019-05-21449 - êwěn之前遇到过一个生产问题,一个服务启动一段时间后就不停的超时,后面结合线程栈发现很多阻塞在打印日志的地方(我们用的就是log4j2),后面查到机子硬盘问题,io直接100%以上,日志刷盘满导致消费速度慢,队列撑满阻塞了写,这间接说明平衡好生产和消费速度以及适当的队列大小是很有必要。
作者回复: 能快速定位的问题👍👍
2019-05-22429 - 苏籍您好老师问个最近用到的线程池使用的问题 我的工程是springboot的,在unitTest里(@SpringBootTest) 里调用了一个service A(通过@Autowired的)中的方法,A中启用了一个线程池,执行的任务 是往数据库里插入数据。但是总抛出数据源已经被关闭的异常,我理解的是在单测主线程已经结束,所以关闭了数据源这些清理工作,而此时线程池的线程还 没结束,这个时候去调用数据源是null 的,不知道这么理解对不对,另外这个test主线程结束,为啥线程池的线程还没结束(通过打断点看到的)。这个怎么理解,求教
作者回复: 只有守护线程才会自动结束,线程池的线程不是守护线程
2019-05-2214 - Asanz看到很多示例代码都没有关闭线程池的动作,难道局部的线程池就不要关闭吗?
作者回复: 需要
2019-08-0812 - 生活发言权请问一下高并发场景,四个人拼一个团,怎么拼? 1.db里记录拼团人数,如果小于4则直接update到拼团用户表,否则创建新的拼团id,新的记录。 2.高并发场景,怎么保证读写db的一致性?redis和db双写? 3.期待老师高见
作者回复: 高并发下,我觉得主要是做好限流和缓存,保护好瓶颈资源数据库,限流和缓存的方案要看流量大小和系统架构
2019-09-1829 - berthav_ss宝令老师,如何优雅的停止线程池中某一组线程呢?例如我在线程a中启动了1-10线程,线程b中启动了2-30线程,如何优雅停止1-10线程呢
作者回复: 可以考虑一下毒丸的方式
2019-06-118 - 来你好我想问下,生产者-消费者模式和worker thread模式有什么区别和联系?我看它们的核心都是任务队列,都是先把任务放到任务队列中,然后再从任务队列中获取任务并执行。
作者回复: 几乎所有多线程程序都会有队列,所以从底层看都是一样的,但是从高层看,是对不同问题的抽象,设计过程是一个从高向低的过程,在高层次只关注模型而不关注实现。
2020-06-035 - Geek_b38255老师你好,想请教下,生产者-消费者模式 与 Worker Thread 模式的区别是什么呢?
作者回复: 很多模式底层实现都是生产者-消费者模式,模式更多地是与现实世界的类比,更多地是一种解决问题的思维方式。从类比的角度,Worker Thread 模式和生产者-消费者模式的区别就出来了,Worker Thread 模式更贴近现实,而生产者-消费者更多的是一种实现层面的模式。
2021-05-011 - Monday第一段代码,非阻塞获取任务时,如果再单批次数量上限比如1000,是不是更好些
作者回复: 会很好������������
2020-12-231
收起评论