问题描述
packageJavaThread;publicclassProducerConsumer{publicstaticvoidmain(String[]args){Basketbasket=newBasket();Producerproducer=newProducer(basket);Consumerconsumer=newConsumer(basket);Threadthread1=newThread(producer);Threadthread2=newThread(consumer);thread1.start();thread2.start();}}classBread{privateStringproducer;Bread(Stringproducer){this.producer=producer;}publicStringtoString(){returnproducer;}}classBasket{privateintindex=0;Bread[]bread=newBread[6];publicsynchronizedvoidpush(Breadb){System.out.println("生产前篮子里面包数:"+index);while(index==bread.length){System.out.println("篮子里满了,开始等待!");try{this.wait();}catch(InterruptedExceptione){e.printStackTrace();}}this.notify();bread[index]=b;//System.out.println("生产了:"+bread[index]);index++;}publicsynchronizedBreadpop(){System.out.println("消费前篮子里面包数为:"+index);while(index==0){System.out.println("篮子里为空,开始等待!");try{this.wait();}catch(InterruptedExceptione){e.printStackTrace();}}index--;returnbread[index];}}classProducerimplementsRunnable{privateBasketbasket;publicProducer(Basketbasket){this.basket=basket;}publicvoidrun(){for(inti=0;i<10;i++){Breadbread=newBread("第"+i+"个面包");basket.push(bread);System.out.println("生产了:"+bread);try{Thread.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}}}}classConsumerimplementsRunnable{privateBasketbasket;publicConsumer(Basketbasket){this.basket=basket;}publicvoidrun(){for(inti=0;i<10;i++){System.out.println("消费了:"+basket.pop());try{Thread.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}}}}
解决方案
解决方案二:
问题:输出结果与预想结果不一致
解决方案三:
publicclassProducerConsumer{publicstaticvoidmain(String[]args){Basketbasket=newBasket();Producerproducer=newProducer(basket);Consumerconsumer=newConsumer(basket);Threadthread1=newThread(producer);Threadthread2=newThread(consumer);thread1.start();thread2.start();}}classBread{privateStringproducer;Bread(Stringproducer){this.producer=producer;}publicStringtoString(){returnproducer;}}classBasket{privateintindex=0;Bread[]bread=newBread[6];publicsynchronizedvoidpush(Breadb){System.out.println("生产前篮子里面包数:"+index);while(index==bread.length){System.out.println("篮子里满了,开始等待!");try{this.wait();}catch(InterruptedExceptione){e.printStackTrace();}}bread[index]=b;index++;this.notify();}publicsynchronizedBreadpop(){System.out.println("消费前篮子里面包数为:"+index);while(index==0){System.out.println("篮子里为空,开始等待!");try{this.wait();}catch(InterruptedExceptione){e.printStackTrace();}}index--;this.notify();returnbread[index];}}classProducerimplementsRunnable{privateBasketbasket;publicProducer(Basketbasket){this.basket=basket;}publicvoidrun(){for(inti=0;i<10;i++){Breadbread=newBread("第"+i+"个面包");basket.push(bread);System.out.println("生产了:"+bread);//try{//Thread.sleep(1);//}catch(InterruptedExceptione){//e.printStackTrace();//}}}}classConsumerimplementsRunnable{privateBasketbasket;publicConsumer(Basketbasket){this.basket=basket;}publicvoidrun(){for(inti=0;i<10;i++){System.out.println("消费了:"+basket.pop());//try{//Thread.sleep(1);//}catch(InterruptedExceptione){//e.printStackTrace();//}}}}
解决方案四:
Thread这方面一直是软肋。学习了,多谢分享!!
解决方案五:
上面程序存在的bug是:假设生产者生产满了篮子,然后就会处于休眠转台,消费者一直在篮子里取面包,等到面包完了以后就处于休眠状态。这时候就是消费者和生产者都处于休眠状态,这个生产消费者系统将不会继续用作。所以要保证系统的正常运行,至少应该在消费者消费完篮子里面的东西时,自我休眠前唤醒生产者来工作。
解决方案六:
Thread.sleep(1);在生产者和消费者中都有这个,是不对的,生产者里这个时间应该是生产一个面包所需要的时间,这个是固定的,为1毫秒也可以,但是在消费者里,消费者来的时间间隔应该是不固定的,随机的,在这里应该模拟随机数作为休眠的时间,这样你就可以得到模拟的真实情况了。修改后:生产者:Thread.sleep(100);消费者://假设消费者来的时间间隔最小为1,最大为1000,产生随机数//取当前时间的毫秒,取模longlTime=System.currentTimeMillis();lTime=lTime/1000+1;Thread.sleep(lTime);修改后运行结果:run:生产前篮子里面包数:0生产了:第0个面包消费前篮子里面包数为:1消费了:第0个面包生产前篮子里面包数:0生产了:第1个面包生产前篮子里面包数:1生产了:第2个面包生产前篮子里面包数:2生产了:第3个面包生产前篮子里面包数:3生产了:第4个面包生产前篮子里面包数:4生产了:第5个面包生产前篮子里面包数:5生产了:第6个面包生产前篮子里面包数:6篮子里满了,开始等待!加上4楼的互相唤醒机制,就ok了........
解决方案七:
两个线程相互独立,没有任何关系,各自有各自的i,也不同步。
解决方案八:
仔细看了下,你的程序问题还挺多的,首先,消费者来的间隔时间不确定,其次,消费者来的多了,很可能要排队,重新修改了程序packagetest;importjava.util.ArrayList;importjava.util.List;publicclassProducerConsumer{privateBasketbasket=newBasket();publicvoidbegin(){Producerproducer=newProducer();Consumerconsumer=newConsumer();Threadthread1=newThread(producer);Threadthread2=newThread(consumer);thread1.start();thread2.start();}classBread{privateStringproducer;Bread(Stringproducer){this.producer=producer;}@OverridepublicStringtoString(){returnproducer;}}classCustom{privateStringcustom;Custom(Stringcustom){this.custom=custom;}@OverridepublicStringtoString(){returncustom;}}classBasket{List<Bread>breadList=newArrayList<Bread>();publicvoidpush(Breadb){if(breadList.size()>5){System.out.println("篮子里满了,请等待!");}else{breadList.add(b);System.out.println("生产后篮子里面包数:"+breadList.size());}}publicBreadpop(){Breadbread=null;if(breadList.size()==0){System.out.println("篮子里为空,请等待!");}else{bread=breadList.get(0);breadList.remove(0);System.out.println("消费后篮子里面包数为:"+breadList.size());}returnbread;}}classProducerimplementsRunnable{publicProducer(){}publicvoidrun(){for(inti=0;i<100;i++){while(basket.breadList.size()>5){try{//如果篮子满了等待时间System.out.println("篮子里满了,生产开始等待!");Thread.sleep(50);}catch(InterruptedExceptione){e.printStackTrace();}}Breadbread=newBread("第"+i+"个面包");basket.push(bread);System.out.println("生产了:"+bread);try{//生产面包所需时间Thread.sleep(200);}catch(InterruptedExceptione){e.printStackTrace();}}}}classConsumerimplementsRunnable{publicConsumer(){}publicvoidrun(){for(inti=0;i<100;i++){while(basket.breadList.size()==0){try{//如果篮子空了等待时间System.out.println("篮子里空了,消费者开始等待!");Thread.sleep(50);}catch(InterruptedExceptione){e.printStackTrace();}}System.out.println("消费了:"+basket.pop());try{//假设消费者来的时间间隔最小为1,最大为200,产生随机数//取当前时间的毫秒,取模longlTime=System.currentTimeMillis();lTime=lTime%300+1;Thread.sleep(lTime);}catch(InterruptedExceptione){e.printStackTrace();}}}}}
程序main类:packagetest;publicclassMain{/***@paramargsthecommandlinearguments*/publicstaticvoidmain(String[]args){//TODOcodeapplicationlogichereProducerConsumerproducer=newProducerConsumer();producer.begin();}}
调整不同的生产时间和消费者产生时间,会看到生产者等待和消费者等待的不同情况。运行结果:run:篮子里空了,消费者开始等待!生产后篮子里面包数:1生产了:第0个面包消费后篮子里面包数为:0消费了:第0个面包生产后篮子里面包数:1生产了:第1个面包消费后篮子里面包数为:0消费了:第1个面包生产后篮子里面包数:1生产了:第2个面包消费后篮子里面包数为:0消费了:第2个面包生产后篮子里面包数:1生产了:第3个面包消费后篮子里面包数为:0消费了:第3个面包生产后篮子里面包数:1生产了:第4个面包消费后篮子里面包数为:0消费了:第4个面包生产后篮子里面包数:1生产了:第5个面包消费后篮子里面包数为:0消费了:第5个面包生产后篮子里面包数:1生产了:第6个面包消费后篮子里面包数为:0消费了:第6个面包生产后篮子里面包数:1生产了:第7个面包消费后篮子里面包数为:0消费了:第7个面包篮子里空了,消费者开始等待!生产后篮子里面包数:1生产了:第8个面包消费后篮子里面包数为:0消费了:第8个面包篮子里空了,消费者开始等待!篮子里空了,消费者开始等待!生产后篮子里面包数:1生产了:第9个面包消费后篮子里面包数为:0消费了:第9个面包生产后篮子里面包数:1生产了:第10个面包消费后篮子里面包数为:0消费了:第10个面包生产后篮子里面包数:1生产了:第11个面包消费后篮子里面包数为:0消费了:第11个面包篮子里空了,消费者开始等待!篮子里空了,消费者开始等待!篮子里空了,消费者开始等待!篮子里空了,消费者开始等待!生产后篮子里面包数:1生产了:第12个面包消费后篮子里面包数为:0消费了:第12个面包生产后篮子里面包数:1生产了:第13个面包消费后篮子里面包数为:0消费了:第13个面包生产后篮子里面包数:1生产了:第14个面包生产后篮子里面包数:2生产了:第15个面包消费后篮子里面包数为:1消费了:第14个面包生产后篮子里面包数:2生产了:第16个面包消费后篮子里面包数为:1消费了:第15个面包消费后篮子里面包数为:0消费了:第16个面包生产后篮子里面包数:1生产了:第17个面包生产后篮子里面包数:2生产了:第18个面包消费后篮子里面包数为:1消费了:第17个面包生产后篮子里面包数:2生产了:第19个面包消费后篮子里面包数为:1消费了:第18个面包消费后篮子里面包数为:0消费了:第19个面包生产后篮子里面包数:1生产了:第20个面包消费后篮子里面包数为:0消费了:第20个面包生产后篮子里面包数:1生产了:第21个面包消费后篮子里面包数为:0消费了:第21个面包生产后篮子里面包数:1生产了:第22个面包消费后篮子里面包数为:0消费了:第22个面包生产后篮子里面包数:1生产了:第23个面包消费后篮子里面包数为:0消费了:第23个面包篮子里空了,消费者开始等待!篮子里空了,消费者开始等待!生产后篮子里面包数:1生产了:第24个面包消费后篮子里面包数为:0消费了:第24个面包生产后篮子里面包数:1生产了:第25个面包消费后篮子里面包数为:0消费了:第25个面包生产后篮子里面包数:1生产了:第26个面包消费后篮子里面包数为:0消费了:第26个面包生产后篮子里面包数:1生产了:第27个面包生产后篮子里面包数:2生产了:第28个面包消费后篮子里面包数为:1消费了:第27个面包消费后篮子里面包数为:0消费了:第28个面包生产后篮子里面包数:1生产了:第29个面包消费后篮子里面包数为:0消费了:第29个面包篮子里空了,消费者开始等待!篮子里空了,消费者开始等待!篮子里空了,消费者开始等待!生产后篮子里面包数:1生产了:第30个面包消费后篮子里面包数为:0消费了:第30个面包生产后篮子里面包数:1生产了:第31个面包消费后篮子里面包数为:0消费了:第31个面包生产后篮子里面包数:1生产了:第32个面包消费后篮子里面包数为:0消费了:第32个面包生产后篮子里面包数:1生产了:第33个面包消费后篮子里面包数为:0消费了:第33个面包生产后篮子里面包数:1生产了:第34个面包消费后篮子里面包数为:0消费了:第34个面包生产后篮子里面包数:1生产了:第35个面包消费后篮子里面包数为:0消费了:第35个面包篮子里空了,消费者开始等待!篮子里空了,消费者开始等待!篮子里空了,消费者开始等待!生产后篮子里面包数:1生产了:第36个面包消费后篮子里面包数为:0消费了:第36个面包篮子里空了,消费者开始等待!篮子里空了,消费者开始等待!生产后篮子里面包数:1生产了:第37个面包消费后篮子里面包数为:0消费了:第37个面包篮子里空了,消费者开始等待!生产后篮子里面包数:1生产了:第38个面包消费后篮子里面包数为:0消费了:第38个面包篮子里空了,消费者开始等待!生产后篮子里面包数:1生产了:第39个面包消费后篮子里面包数为:0消费了:第39个面包篮子里空了,消费者开始等待!篮子里空了,消费者开始等待!
解决方案九:
可以看看张孝祥的银行业务调度,差别是这个只有一个生产者,一个篮子,张老师的有多个窗口,相当于多个篮子,多个生产者,还有不同的客户,就相当于每个客户买的面包数量不同。
解决方案十:
上面的例子还是有问题,重新修改下,客户可以购买最多3个面包:importjava.util.ArrayList;importjava.util.List;/****@authorpantianzhu*/publicclassProducerConsumer{privateBasketbasket=newBasket();publicvoidbegin(){Producerproducer=newProducer();Consumerconsumer=newConsumer();Threadthread1=newThread(producer);Threadthread2=newThread(consumer);Threadthread3=newThread(basket);thread1.start();thread2.start();thread3.run();}classBread{privateStringproducer;Bread(Stringproducer){this.producer=producer;}@OverridepublicStringtoString(){returnproducer;}}classCustom{privateStringcustom;privateintbreads;Custom(Stringcustom,intbreads){this.custom=custom;this.breads=breads;}@OverridepublicStringtoString(){returncustom;}}classBasketimplementsRunnable{List<Bread>breadList=newArrayList<Bread>();List<Custom>custList=newArrayList<Custom>();publicvoidpush(Breadb){if(breadList.size()>5){System.out.println("篮子里满了,请等待!");}else{breadList.add(b);System.out.println("生产后篮子里面包数:"+breadList.size());}}publicBreadpop(){Breadbread=null;if(breadList.size()==0){System.out.println("篮子里为空,请等待!");}else{bread=breadList.get(0);breadList.remove(0);//System.out.println("消费后篮子里面包数为:"+breadList.size()+",排队的客户数"+custList.size());}returnbread;}publicvoidrun(){while(true){if(custList.size()>0){Customcustom=custList.get(0);for(inti=0;i<custom.breads;i++){booleansucc=false;while(!succ){Breadbread=pop();if(bread!=null){System.out.println(custList.get(0)+"消费了"+bread.toString());succ=true;}else{try{Thread.sleep(50);}catch(InterruptedExceptione){e.printStackTrace();}}}}custList.remove(0);System.out.println("消费后篮子里面包数为:"+breadList.size()+",排队的客户数"+custList.size());}try{Thread.sleep(50);}catch(InterruptedExceptione){e.printStackTrace();}}}}classProducerimplementsRunnable{publicProducer(){}publicvoidrun(){for(inti=0;i<100;i++){while(basket.breadList.size()>5){try{//如果篮子满了等待时间System.out.println("篮子里满了,生产开始等待!");Thread.sleep(50);}catch(InterruptedExceptione){e.printStackTrace();}}Breadbread=newBread("第"+i+"个面包");basket.push(bread);System.out.println("生产了:"+bread);try{//生产面包所需时间Thread.sleep(150);}catch(InterruptedExceptione){e.printStackTrace();}}}}classConsumerimplementsRunnable{publicConsumer(){}publicvoidrun(){for(inti=0;i<20;i++){longlbuys;intbuys=0;//假设消费者购买数最小为1,最大为3,产生随机数//取当前时间的毫秒,取模lbuys=System.currentTimeMillis();buys=(int)(lbuys%3)+1;Customcustom=newCustom("第"+i+"个客户",buys);basket.custList.add(custom);System.out.println("产生了"+custom.toString()+",要购买"+custom.breads+"个面包");try{//假设消费者来的时间间隔最小为1,最大为200,产生随机数//取当前时间的毫秒,取模longlTime=System.currentTimeMillis();lTime=lTime%400+1;Thread.sleep(lTime);}catch(InterruptedExceptione){e.printStackTrace();}}}}}
run:产生了第0个客户,要购买2个面包生产后篮子里面包数:1生产了:第0个面包第0个客户消费了第0个面包篮子里为空,请等待!篮子里为空,请等待!篮子里为空,请等待!生产后篮子里面包数:1生产了:第1个面包第0个客户消费了第1个面包消费后篮子里面包数为:0,排队的客户数0生产后篮子里面包数:1生产了:第2个面包产生了第1个客户,要购买2个面包第1个客户消费了第2个面包篮子里为空,请等待!生产后篮子里面包数:1生产了:第3个面包第1个客户消费了第3个面包消费后篮子里面包数为:0,排队的客户数0生产后篮子里面包数:1生产了:第4个面包产生了第2个客户,要购买3个面包第2个客户消费了第4个面包篮子里为空,请等待!篮子里为空,请等待!生产后篮子里面包数:1生产了:第5个面包第2个客户消费了第5个面包篮子里为空,请等待!产生了第3个客户,要购买1个面包篮子里为空,请等待!篮子里为空,请等待!生产后篮子里面包数:1生产了:第6个面包第2个客户消费了第6个面包消费后篮子里面包数为:0,排队的客户数1篮子里为空,请等待!篮子里为空,请等待!生产后篮子里面包数:1生产了:第7个面包第3个客户消费了第7个面包消费后篮子里面包数为:0,排队的客户数0产生了第4个客户,要购买3个面包篮子里为空,请等待!篮子里为空,请等待!生产后篮子里面包数:1生产了:第8个面包第4个客户消费了第8个面包篮子里为空,请等待!篮子里为空,请等待!篮子里为空,请等待!产生了第5个客户,要购买3个面包产生了第6个客户,要购买2个面包生产后篮子里面包数:1生产了:第9个面包第4个客户消费了第9个面包篮子里为空,请等待!篮子里为空,请等待!产生了第7个客户,要购买1个面包篮子里为空,请等待!生产后篮子里面包数:1生产了:第10个面包第4个客户消费了第10个面包消费后篮子里面包数为:0,排队的客户数3产生了第8个客户,要购买2个面包篮子里为空,请等待!生产后篮子里面包数:1生产了:第11个面包第5个客户消费了第11个面包篮子里为空,请等待!篮子里为空,请等待!篮子里为空,请等待!生产后篮子里面包数:1生产了:第12个面包第5个客户消费了第12个面包篮子里为空,请等待!篮子里为空,请等待!篮子里为空,请等待!产生了第9个客户,要购买1个面包生产后篮子里面包数:1生产了:第13个面包第5个客户消费了第13个面包消费后篮子里面包数为:0,排队的客户数4篮子里为空,请等待!篮子里为空,请等待!生产后篮子里面包数:1生产了:第14个面包第6个客户消费了第14个面包篮子里为空,请等待!产生了第10个客户,要购买3个面包篮子里为空,请等待!篮子里为空,请等待!生产后篮子里面包数:1生产了:第15个面包第6个客户消费了第15个面包消费后篮子里面包数为:0,排队的客户数4产生了第11个客户,要购买3个面包篮子里为空,请等待!篮子里为空,请等待!生产后篮子里面包数:1生产了:第16个面包第7个客户消费了第16个面包消费后篮子里面包数为:0,排队的客户数4篮子里为空,请等待!产生了第12个客户,要购买3个面包篮子里为空,请等待!产生了第13个客户,要购买2个面包生产后篮子里面包数:1生产了:第17个面包第8个客户消费了第17个面包篮子里为空,请等待!产生了第14个客户,要购买3个面包篮子里为空,请等待!篮子里为空,请等待!产生了第15个客户,要购买1个面包生产后篮子里面包数:1生产了:第18个面包第8个客户消费了第18个面包消费后篮子里面包数为:0,排队的客户数7篮子里为空,请等待!篮子里为空,请等待!生产后篮子里面包数:1生产了:第19个面包第9个客户消费了第19个面包消费后篮子里面包数为:0,排队的客户数6产生了第16个客户,要购买1个面包篮子里为空,请等待!产生了第17个客户,要购买3个面包篮子里为空,请等待!产生了第18个客户,要购买1个面包生产后篮子里面包数:1生产了:第20个面包第10个客户消费了第20个面包篮子里为空,请等待!篮子里为空,请等待!产生了第19个客户,要购买3个面包篮子里为空,请等待!生产后篮子里面包数:1生产了:第21个面包第10个客户消费了第21个面包篮子里为空,请等待!篮子里为空,请等待!
解决方案十一:
packageJavaThread;publicclassProducerConsumer{publicstaticvoidmain(String[]args){Basketbasket=newBasket();Producerproducer=newProducer(basket);Consumerconsumer=newConsumer(basket);Threadthread1=newThread(producer);Threadthread2=newThread(consumer);thread1.start();thread2.start();}}classBread{privateStringproducer;Bread(Stringproducer){this.producer=producer;}publicStringtoString(){returnproducer;}}classBasket{privateintindex=0;Bread[]bread=newBread[6];publicsynchronizedvoidpush(Breadb){System.out.println("生产前篮子里面包数:"+index);while(index==bread.length){System.out.println("篮子里满了,开始等待!");try{this.wait();}catch(InterruptedExceptione){e.printStackTrace();}}this.notify();bread[index]=b;//System.out.println("生产了:"+bread[index]);index++;}publicsynchronizedBreadpop(){System.out.println("消费前篮子里面包数为:"+index);while(index==0){System.out.println("篮子里为空,开始等待!");try{this.wait();}catch(InterruptedExceptione){e.printStackTrace();}}index--;returnbread[index];}}classProducerimplementsRunnable{privateBasketbasket;publicProducer(Basketbasket){this.basket=basket;}publicvoidrun(){for(inti=0;i<10;i++){Breadbread=newBread("第"+i+"个面包");basket.push(bread);System.out.println("生产了:"+bread);try{Thread.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}}}}classConsumerimplementsRunnable{privateBasketbasket;publicConsumer(Basketbasket){this.basket=basket;}publicvoidrun(){for(inti=0;i<10;i++){System.out.println("消费了:"+basket.pop());try{Thread.sleep(1);}catch(InterruptedExceptione){e.printStackTrace();}}}}
上面是楼主的程序,楼主开启了两个线程,就出现了死等待解决办法:第一种:把while循化,给我if判断。第二种:把this.notify改为this.notifyAll()
解决方案十二:
字打错了,不是给我,是“改为”