Java实现多线程中生产者、消费者问题,简单易懂
2022/2/1 20:39:33
本文主要是介绍Java实现多线程中生产者、消费者问题,简单易懂,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
思想:
1、生产者在while循环里不停地生产“产品”,每生产一个,就交给店员,店员就得到一个产品
2、消费者在while循环里不停地消费产品,每消费一个,店员就移走一个产品
3、店员手里的产品少于20个,就从生产者那里拿走产品。等于20个,就停止从生产者那里拿走产品
4、店员手里的产品多于0个,就让消费者消费产品。等于0个,就停止让消费者消费产品
生产者:
生产者在while循环里不停地生产“产品”,每生产一个,就交给店员,店员就得到一个产品
//生产者 class Producter implements Runnable{ Clerk clerk; Producter(Clerk clerk){ this.clerk=clerk; } @Override public void run() { while (true){ //此处可加sleep,让生产者生产的慢一点 clerk.getProduce();//生产者不停地生产产品,生产一个,就交给店员,店员就get一个 } } }
消费者:
消费者在while循环里不停地消费产品,每消费一个,店员就移走一个产品
//消费者 class Consummer implements Runnable{ Clerk clerk; Consummer(Clerk clerk){ this.clerk=clerk; } @Override public void run() { while (true){ //此处可加sleep,让消费者消费的慢一些 clerk.removeProduce();//消费者不停地消费产品,消费一个,店员处就remove一个 } } }
店员:
店员手里的产品少于20个,就从生产者那里拿走产品。等于20个,就停止从生产者那里拿走产品
店员手里的产品多于0个,就让消费者消费产品。等于0个,就停止让消费者消费产品
//店员 class Clerk{ public int producenumber;//店员手里产品的数量 public synchronized void getProduce() {//锁是clerk,反复执行的实际上是该方法和removeProduce方法 if(producenumber<20){//店员手里产品数量少于20个,就从生产者那里拿过来一个 producenumber++; System.out.println(Thread.currentThread().getName()+"生产了第"+producenumber+"个产品"); notify();//已经从生产者那里拿过来一个产品了,说明手里肯定是有产品的,店员可以让消费者拿走产品了 }else{ try { wait();//店员手里产品数量多于20个,停止从生产者那里拿走产品 } catch (InterruptedException e) { System.out.println(e.getMessage()); } } } public synchronized void removeProduce(){//锁是clerk,相当于四个线程一个一个的执行 if(producenumber>0){//店员手里产品数量多余0个,就让消费者拿走产品 System.out.println(Thread.currentThread().getName()+"消费了第"+producenumber+"个产品"); producenumber--; notify();//已经让消费者拿走了一个产品,说明柜台肯定有位置放产品,店员可以从生产者那里取产品了 }else{ try { wait();//店员手里产品数量少于0个,停止让消费者拿走产品 } catch (InterruptedException e) { System.out.println(e.getMessage()); } } } }
测试类:
public class ThreadCommunicationTest { public static void main(String[] args) { Clerk clerk=new Clerk(); Producter p=new Producter(clerk); Thread tp1=new Thread(p); tp1.setName("生产者1"); tp1.start(); Thread tp2=new Thread(p); tp2.setName("生产者2"); tp2.start(); Consummer c=new Consummer(clerk); Thread tc1=new Thread(c); tc1.setName("消费者1"); tc1.start(); Thread tc2=new Thread(c); tc2.setName("消费者2"); tc2.start(); } }
Attention:
一共有四个线程:生产者1、生产者2、消费者1、消费者2
生产者1和生产者2线程开启后,调用Producter类里的run方法,又在run方法里调用Clerk类里的getProduce方法
相当于生产者1和生产者2反复执行的是getProduce方法
生产者1和生产者2线程开启后,调用PConsummer类里的run方法,又在run方法里调用Clerk类里的removeProduce方法
相当于消费者1和消费者2反复执行的是removeProduce方法
而getProduce方法和removeProduce方法都是同步方法,它们都在Clerk类中定义,而Clerk类从始至终只有一个对象,所以两个同步方法的锁是同一把,即Clerk类的实例对象clerk
意味着在两个方法中,四个线程只能一个一个的执行,因此线程安全
执行截图:
这篇关于Java实现多线程中生产者、消费者问题,简单易懂的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-23线下车企门店如何实现线上线下融合?
- 2024-12-23鸿蒙Next ArkTS编程规范总结
- 2024-12-23物流团队冬至高效运转,哪款办公软件可助力风险评估?
- 2024-12-23优化库存,提升效率:医药企业如何借助看板软件实现仓库智能化
- 2024-12-23项目管理零负担!轻量化看板工具如何助力团队协作
- 2024-12-23电商活动复盘,为何是团队成长的核心环节?
- 2024-12-23鸿蒙Next ArkTS高性能编程实战
- 2024-12-23数据驱动:电商复盘从基础到进阶!
- 2024-12-23从数据到客户:跨境电商如何通过销售跟踪工具提升营销精准度?
- 2024-12-23汽车4S店运营效率提升的核心工具