《重学Java高并发》之“摸底考试”:你会使用多线程实现生产者-消费者协作模型吗? 原创

简介: 《重学Java高并发》之“摸底考试”:你会使用多线程实现生产者-消费者协作模型吗?原创

1、消费者/生产者场景


一个非常经典的场景:面包厂生产面包。


在一个面包厂,面包的仓库容积有限,生产工人可以继续生产面包的条件是仓库还有足够的空间,生产的面包是需要派送工人卖给顾客,派送工人要能派送面包的条件是仓库中有剩余的面包。


大概的场景到交付如下图所示:

1142bb4880382433ea13659953c91c3c.png

2、代码实现


有了场景,接下来我们使用java写一个简易的生产者、消费者。


本示例中涉及到类主要如下图所示:

05c9d90667c8822956216c0bd9af88c2.png

其类的职责说明如下:


  • Bakery 面包厂仓库,主要用来存放面包。
  • BreadWork 面包生产工人
  • BreadConsume 面包消费工人
  • Bread 面包


接下来将和大家一一展示代码,同时在介绍代码时将重点阐述线程合作时的一些重点知识,并将提出一个更高难度的思考题供大家挑战。


2.1 Bakery核心实现


Bakery是整个生产者、消费者模型的核心实现类,与多线程编程相关的核心要点也体现在该方法中,其整体代码如下:

538aa54b5ab5b06740bb6ea857c0791b.png

其核心要点解释如下:


  • Object bakeryLock 锁对象,主要是用来保护List< Bread> 数据结构,众所周知,ArrayList是多线程不安全的,也就是说多个线程对其进行访问,必须加锁,这里之所以单独创建一个对象,主要是想突出锁概念,在代码中,其实可以用 synchronized(breads) 来代替。
  • put方法 该方法是被面包生产者调用,向面包厂中添加面包,但是面包厂的容量是有限的,即生产者不能一直往里面添加,即当达到最大容量后,需要阻止生产者继续往里面添加,故这里涉及到条件等待与wait方法,细细说明如下:
  • 访问breads数据结构之前,先使用synchronized进行保护,即加锁。
  • 如果仓库已满,需要调用锁对象的wait方法,调用锁对象的线程,也就是生产者线程会被阻塞,需要等待其他线程的唤醒,唤醒后才能继续执行后续代码。
  • 如果仓库还有空间,则向仓库中添加一个面包,此时另外一个隐含的条件将满足:仓库中已经有面包了,而消费者可能会因为仓库中没有面包而阻塞,故这里需要调用锁对象的notify或nofifyAll方法,唤醒等待的消费者。
  • get方法 该方法主要是被面包消费者调用,从面包中获取面包,但要能获取面包也是有条件的:仓库中存在面包,否则需要阻塞等待消费者创建面包,故这里的要点如下:
  • 如果仓库中没有面包,调用锁对象的wait方法,则消费者线程将进入阻塞状态,其具体实现是消费者线程对象会放在锁对象的条件等待队列,将等待其他线程调用锁的notify或notifyAll。
  • 如果有面包,则从中消费一个面包,此时另外一个隐含的条件将满足:仓库中已经有新的空间存放新的面包,故此时应该调用锁对象的notify或notifyAll,唤醒生产者。


2.2 生产者/消费者代码实现


在该示例中生产者、消费者创建面包,并尝试存储在面包厂中,其代码示例如下:

110d52efda286c1266c108cbb4af0b13.png

消费者、生产者代码比较简单,就不做过多说明。


温馨提示:如果需要整套代码,可以私信我,回复TCODE即可获得。


2.3 运行效果与进阶


该示例的运行效果如下图所示:

1ab0e0f373c951d6a5d37d9ea3ca333e.png

上面的示例其实只是一个入门,重点是了解锁对象,线程之间如何通过notify、wait方法进行协同“作战”,有了上面的示例,我想将难度系数再次提高:


如果做到生产者、消费者交替运行,即生产者生产面包1号,需要等待消费者消费完面包1号后,生产者才能继续生产2号面包。

相关文章
|
9月前
|
Java 大数据 Go
从混沌到秩序:Java共享内存模型如何通过显式约束驯服并发?
并发编程旨在混乱中建立秩序。本文对比Java共享内存模型与Golang消息传递模型,剖析显式同步与隐式因果的哲学差异,揭示happens-before等机制如何保障内存可见性与数据一致性,展现两大范式的深层分野。(238字)
264 4
|
11月前
|
缓存 前端开发 Java
Java类加载机制与双亲委派模型
本文深入解析Java类加载机制,涵盖类加载过程、类加载器、双亲委派模型、自定义类加载器及实战应用,帮助开发者理解JVM核心原理与实际运用。
|
11月前
|
机器学习/深度学习 人工智能 自然语言处理
Java 大视界 -- Java 大数据机器学习模型在自然语言生成中的可控性研究与应用(229)
本文深入探讨Java大数据与机器学习在自然语言生成(NLG)中的可控性研究,分析当前生成模型面临的“失控”挑战,如数据噪声、标注偏差及黑盒模型信任问题,提出Java技术在数据清洗、异构框架融合与生态工具链中的关键作用。通过条件注入、强化学习与模型融合等策略,实现文本生成的精准控制,并结合网易新闻与蚂蚁集团的实战案例,展示Java在提升生成效率与合规性方面的卓越能力,为金融、法律等强监管领域提供技术参考。
|
11月前
|
机器学习/深度学习 算法 Java
Java 大视界 -- Java 大数据机器学习模型在生物信息学基因功能预测中的优化与应用(223)
本文探讨了Java大数据与机器学习模型在生物信息学中基因功能预测的优化与应用。通过高效的数据处理能力和智能算法,提升基因功能预测的准确性与效率,助力医学与农业发展。
|
11月前
|
机器学习/深度学习 搜索推荐 数据可视化
Java 大视界 -- Java 大数据机器学习模型在电商用户流失预测与留存策略制定中的应用(217)
本文探讨 Java 大数据与机器学习在电商用户流失预测与留存策略中的应用。通过构建高精度预测模型与动态分层策略,助力企业提前识别流失用户、精准触达,实现用户留存率与商业价值双提升,为电商应对用户流失提供技术新思路。
|
存储 SQL 缓存
Java高并发秒杀系统【观后总结】(四)
在慕课网上发现了一个JavaWeb项目,内容讲的是高并发秒杀,觉得挺有意思的,就进去学习了一番。
492 0
Java高并发秒杀系统【观后总结】(四)
|
SQL 缓存 NoSQL
Java高并发秒杀系统【观后总结】(三)
在慕课网上发现了一个JavaWeb项目,内容讲的是高并发秒杀,觉得挺有意思的,就进去学习了一番。
376 0
Java高并发秒杀系统【观后总结】(三)
|
JSON JavaScript 前端开发
Java高并发秒杀系统【观后总结】(二)
在慕课网上发现了一个JavaWeb项目,内容讲的是高并发秒杀,觉得挺有意思的,就进去学习了一番。
371 0
Java高并发秒杀系统【观后总结】(二)
|
XML Java 数据库连接
Java高并发秒杀系统【观后总结】(一)
在慕课网上发现了一个JavaWeb项目,内容讲的是高并发秒杀,觉得挺有意思的,就进去学习了一番。
435 0
Java高并发秒杀系统【观后总结】(一)
|
前端开发 Java 数据库连接
Java高并发秒杀系统【观后总结】
项目简介 在慕课网上发现了一个JavaWeb项目,内容讲的是高并发秒杀,觉得挺有意思的,就进去学习了一番。 记录在该项目中学到了什么玩意.. 该项目源码对应的gitHub地址(由观看其视频的人编写,并非视频源代码):https://github.com/codingXiaxw/seckill 我结合其资料和观看视频的时候整理出从该项目学到了什么... 项目Dao层 日志记录工具: Mybatis之前没注意到的配置属性: 使用jdbc的getGeneratekeys获取自增主键值,这个属性还是挺有用的。
1793 0

热门文章

最新文章