[Java]多线程之生产者消费者优化版

优化版,可以把生产和消费过程全部集中在baozi 里,生产者和消费者只需要下指令就好

重点是如何在baozi内实现两个方法:

对于生产者而言,true时没有包子,需要生产,生产完了,要通知正在等待的消费者,同时要置为false,表示已经有包子了,

False下,生产者就是要等待,等待消费者传来消息

 

对于消费者来说,false时有包子,可以去拿,拿了包子要通知生产者,置为truetrue的状态下等生产者发来消息

OK,走起,出问题,一直在生产一种包子

有误版的资源池:

package com.rjl.producerAndcustomer;
	public class Baozi {
	    private  String name;
	    private   int    price;    
	    boolean flag=false;
	    
	    public synchronized void set(String name, int price){  
			 if(!this.flag){			 
				 //true的时候要生产包子
	        		 this.name=name;
	    	    	 this.price =price;
					 //生产完了置为true
	    	    	 this.flag=true;
					 //通知
	    	    	 this.notify(); 
	    	    	 System.out.println("Producer set "+ this.name+"  "+this.price  );
	    	 }
	    	 else {
	    		 try {				 
						this.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
			 }    	   	
	    }    
	    public synchronized void get(){  	
	    	//生产者生产了包子,flag为true,此时拿包子
			if (this.flag) {
	    	    	 System.out.println("Customer got "+ this.name+"  "+this.price  );
				     //拿了就置为false
					 this.flag=false;
					 //通知
				     this.notify();
			}
	    	else {
	    		try {
					this.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} 	
		}
	}


 

 

问题在哪?

生产者和消费者的线程谁先启动要看CPU的调度,具有随机性

假如生产者的线程先启动,此时生产狗不理,生产了要notify,而这个时候消费者的线程有可能还没起来,又去调度生产者,这个时候x自增了,变成1,按理说这个时候要生产猪扒包,但是这个时候flag还是true,因为没有消费者去置为false,也即是说生产者只能走到else的代码块里,在else里就只能等待,被挂起了,什么也做不了,那么这时候可以去调度消费者的线程,正好true可以拿,把flag置为false,并且通知生产者

这个时候生产者在else里被挂起,CPU调度他走起,什么也不做,直接退出了,相当于什么也没生产,又从头开始生产,还是狗不理。

有可能如此循环数次

    逻辑上的错误,没就生产,有就等待,这并不是一个if-else的关系

如何修改?问题是出在消费者没启动从而使生产者进入挂起状态,那么现在就应该做到,即使消费者没启动,回来进生产者不是挂机而是依然判断一下,然后找消费者,直到消费者启动了,消费了这个包子,换个角度,一定要生产包子,然后等,等了之后一定还要生产,不能等完了就结束了。

那么,生产者的线程启动时,应该先判断是否是true,需要挂起,挂起了就转去消费者,即使这个时候消费者的线程依然没启动,回来还是在判断,判断了挂机,还是去找消费者,如此循环,直到消费者启动了。

同样,消费者也是先判断,是否是需要等待挂起,不需要等待才去拿包子

 最终版资源池:

public class Baozi {
    private  String name;
    private   int    price;   
    boolean flag=false; 
	//先判断是否需要挂起
    public synchronized void set(String name, int price){ 	
    	 if( this.flag){    		 
    		 try {				 
					this.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}	
    	 }		   	 
    	 this.name=name;
    	 this.price =price;
    	 this.flag=true;
    	 this.notify(); 
    	 System.out.println("Producer set "+ this.name+"  "+this.price  );   	     	 
	   }
  
    public synchronized void get(){  	
    	if (!this.flag) {
    		try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}	
		 }	
    	System.out.println("Customer got "+ this.name+"  "+this.price  );
    	this.flag=false;
    	this.notify();    	
    }
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值