多线程系列之生产者和消费者

在之前接触过PV操作的,应该对于生产者和消费者的情况有一个了解,这里学到多线程同步的时候,最恰当的一个例子。PV操作就不多做解释。

/**
 * 生产者和消费者
 * @author bobo
 *
 */
public class ProducerConsumer  {

	public static void main(String[] args) {
		SyncStack ss=new SyncStack();
		Producer p=new Producer(ss);
		Consumer c=new Consumer(ss);
		
		new Thread(p).start();
		new Thread(p).start();
		new Thread(c).start();
		new Thread(c).start();
	}
}

//产品-窝头
class WoTou{
	
	int id;
	public WoTou(int id){
		this.id=id;
	}
	public String toString(){
		return "WOTou : "+id;
	}
}

//同步栈,产品盛放的容器 
class SyncStack{
	int index=0;
	WoTou[] arrWT=new WoTou[6];
	
	//向容器中放产品时,其他线程不能使用,已经被锁定
	public synchronized void push(WoTou wt){
		while(index==arrWT.length){
			try {
				this.wait();
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			}			
		}
		this.notifyAll();//通知消费者,可使用产品
		arrWT[index]=wt;
		index++;//放入产品
	}
	
	//向容器中拿产品时,其他线程不能使用,已经被锁定
	public synchronized  WoTou pop(){
		while(index==0){
			try {
				this.wait();//如果可拿资源为0,线程等待
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			}
		}
		this.notifyAll();//通知生产者,可以进行生产
		index--;
		return arrWT[index];//栈中有空位
	}
}

//生产者,向容器中放产品
class Producer implements Runnable{
	SyncStack ss=null;
	Producer(SyncStack ss){
		this.ss=ss;
	}
	public void run(){
		for(int i=0;i<20;i++){
			WoTou wt= new WoTou(i);
			ss.push(wt);
			System.out.println("生产者生成:"+wt);
			try {
				Thread.sleep((int)(Math.random()*200));
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			}
		}
	}
}

//消费者,从容器中取产品
class Consumer implements Runnable{
	SyncStack ss=null;
	Consumer(SyncStack ss){
		this.ss=ss;
	}
	
	public void run(){
		for(int i=0;i<20;i++){
			WoTou wt=ss.pop();
			System.out.println("消费者消费:"+wt);
			try {
				Thread.sleep((int)(Math.random()*1000));
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			}
		}
	}
}


       有一个容器可以装产品,两边是生产者和消费者,可以是一个也可以是多个。他们为了保证生产者放一个,消费者拿一个,同时也不会出现,生产者还没有放,消费者就可以去拿了,那会使容器中的产品出现负数,这样显然是不对的。


       使用synchronized锁定代码块,让生产者向容器放东西的时候,消费者还不能拿到这个产品。

补充:

notify()/notifyAll()

通知,在生产者和消费者这个问题上,当生产者产生产品以后,可以通过信号量,通知消费者,它已经获得了资源。可以进行消费了。

防止大家都在等待,而造成线程阻塞。

wait()和sleep()区别

wait()是Object类中的方法,之后其他人可以使用

sleep()是Thread类的方法,之后其他人也不可以使用




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值