Java 并发编程实战
王宝令
资深架构师
72486 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 51 讲
学习攻略 (1讲)
Java 并发编程实战
15
15
1.0x
00:00/00:00
登录|注册

36 | 生产者-消费者模式:用流水线思想提高效率

课后思考
总结
支持分阶段提交以提升性能
支持批量执行以提升性能
优点
生产者-消费者模式

该思维导图由 AI 生成,仅供参考

前面我们在《34 | Worker Thread 模式:如何避免重复创建线程?》中讲到,Worker Thread 模式类比的是工厂里车间工人的工作模式。但其实在现实世界,工厂里还有一种流水线的工作模式,类比到编程领域,就是生产者 - 消费者模式
生产者 - 消费者模式在编程领域的应用也非常广泛,前面我们曾经提到,Java 线程池本质上就是用生产者 - 消费者模式实现的,所以每当使用线程池的时候,其实就是在应用生产者 - 消费者模式。
当然,除了在线程池中的应用,为了提升性能,并发编程领域很多地方也都用到了生产者 - 消费者模式,例如 Log4j2 中异步 Appender 内部也用到了生产者 - 消费者模式。所以今天我们就来深入地聊聊生产者 - 消费者模式,看看它具体有哪些优点,以及如何提升系统的性能。

生产者 - 消费者模式的优点

生产者 - 消费者模式的核心是一个任务队列,生产者线程生产任务,并将任务添加到任务队列中,而消费者线程从任务队列中获取任务并执行。下面是生产者 - 消费者模式的一个示意图,你可以结合它来理解。
生产者 - 消费者模式示意图
从架构设计的角度来看,生产者 - 消费者模式有一个很重要的优点,就是解耦。解耦对于大型系统的设计非常重要,而解耦的一个关键就是组件之间的依赖关系和通信方式必须受限。在生产者 - 消费者模式中,生产者和消费者没有任何依赖关系,它们彼此之间的通信只能通过任务队列,所以生产者 - 消费者模式是一个不错的解耦方案
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

生产者-消费者模式在并发编程中的应用是一种重要的技术实践。本文深入探讨了该模式的优点和在性能优化方面的应用。通过示例代码展示了如何利用生产者-消费者模式实现批量执行SQL和异步刷盘的应用场景。文章还提到了Java语言提供的线程池本身就是一种生产者-消费者模式的实现,但在某些场景下仍需要自行实现。此外,生产者-消费者模式在分布式计算中也有广泛应用,可以借助分布式消息队列来实现。在课后思考部分,作者提出了关于优雅终止写日志线程的问题,鼓励读者分享自己的想法和思考过程。整体而言,本文为读者提供了丰富的实践经验和技术指导,对于想要深入了解生产者-消费者模式的读者具有很高的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 并发编程实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(42)

  • 最新
  • 精选
  • 在应用系统中,日志系统一般都是最后关闭的吧,因为它要为其他系统关闭提供写日志服务。所以日志系统关闭时需要把队列中所有日志都消费掉才能关闭。 可能需要在关闭日志系统时投入一个毒丸,表示没有新的日志写入。线程池在消费到毒丸时知道没有日志写入,将所有的日志刷盘,break循环体。

    作者回复: 👍

    2019-05-21
    138
  • PK時頭髮不亂
    极客时间有好多课程, 我觉得王老师的干货是最实际最可用的, 必须要赞一个。

    作者回复: 感谢感谢,有钱难买合适:)

    2019-05-21
    4
    49
  • êwěn
    之前遇到过一个生产问题,一个服务启动一段时间后就不停的超时,后面结合线程栈发现很多阻塞在打印日志的地方(我们用的就是log4j2),后面查到机子硬盘问题,io直接100%以上,日志刷盘满导致消费速度慢,队列撑满阻塞了写,这间接说明平衡好生产和消费速度以及适当的队列大小是很有必要。

    作者回复: 能快速定位的问题👍👍

    2019-05-22
    4
    29
  • 苏籍
    您好老师问个最近用到的线程池使用的问题 我的工程是springboot的,在unitTest里(@SpringBootTest) 里调用了一个service A(通过@Autowired的)中的方法,A中启用了一个线程池,执行的任务 是往数据库里插入数据。但是总抛出数据源已经被关闭的异常,我理解的是在单测主线程已经结束,所以关闭了数据源这些清理工作,而此时线程池的线程还 没结束,这个时候去调用数据源是null 的,不知道这么理解对不对,另外这个test主线程结束,为啥线程池的线程还没结束(通过打断点看到的)。这个怎么理解,求教

    作者回复: 只有守护线程才会自动结束,线程池的线程不是守护线程

    2019-05-22
    14
  • Asanz
    看到很多示例代码都没有关闭线程池的动作,难道局部的线程池就不要关闭吗?

    作者回复: 需要

    2019-08-08
    12
  • 生活发言权
    请问一下高并发场景,四个人拼一个团,怎么拼? 1.db里记录拼团人数,如果小于4则直接update到拼团用户表,否则创建新的拼团id,新的记录。 2.高并发场景,怎么保证读写db的一致性?redis和db双写? 3.期待老师高见

    作者回复: 高并发下,我觉得主要是做好限流和缓存,保护好瓶颈资源数据库,限流和缓存的方案要看流量大小和系统架构

    2019-09-18
    2
    9
  • berthav_ss
    宝令老师,如何优雅的停止线程池中某一组线程呢?例如我在线程a中启动了1-10线程,线程b中启动了2-30线程,如何优雅停止1-10线程呢

    作者回复: 可以考虑一下毒丸的方式

    2019-06-11
    8
  • 你好我想问下,生产者-消费者模式和worker thread模式有什么区别和联系?我看它们的核心都是任务队列,都是先把任务放到任务队列中,然后再从任务队列中获取任务并执行。

    作者回复: 几乎所有多线程程序都会有队列,所以从底层看都是一样的,但是从高层看,是对不同问题的抽象,设计过程是一个从高向低的过程,在高层次只关注模型而不关注实现。

    2020-06-03
    5
  • Geek_b38255
    老师你好,想请教下,生产者-消费者模式 与 Worker Thread 模式的区别是什么呢?

    作者回复: 很多模式底层实现都是生产者-消费者模式,模式更多地是与现实世界的类比,更多地是一种解决问题的思维方式。从类比的角度,Worker Thread 模式和生产者-消费者模式的区别就出来了,Worker Thread 模式更贴近现实,而生产者-消费者更多的是一种实现层面的模式。

    2021-05-01
    1
  • Monday
    第一段代码,非阻塞获取任务时,如果再单批次数量上限比如1000,是不是更好些

    作者回复: 会很好������������

    2020-12-23
    1
收起评论
显示
设置
留言
42
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部