Java:线程同步经典案例-生产者与消费者模型

1 相关知识简介

在生产者-消费者模型中,若只使用synchronized关键字实现对象锁,程序在运行中可能会出现以下两种情况:

  1. 若生产者的速度大于消费者,那么在消费者来不及取前一个数据之前,生产者又产生了新的数据,于是消费者很可能会跳过前一个数据。
  2. 若消费者的速度大于生产者,那么消费者可能多次取同一个数据。
  • 为了避免上述情况,必须使生产者向object对象中存储数据与消费者从object对象中取走数据同步起来。因此,在程序中可以采用信号量模型,同时通过调用对象的wait方法和notifyAll方法来实现同步。
  • 信号量模型的工作方式:线程在运行的过程中,可以主动停下来,等待某个信号量的通知,此时该线程就进入到该信号量的等待队列中,直到得到通知后,再继续运行。在Java语言中,Object对象的wait方法就是等待通知,notifynotifyAll方法就是发出通知,唤醒在该信号量的等待队列里面的相关线程。


2 生产者-消费者模型的案例

package JavaPrograms;

/*
 * 该类的对象为共享资源
 * 新增信号量available:当为true时,表示数据已经产生但还没被取走;
 * 当为false时,表示数据已经被取走但还没有存放新的数据。
 */
class MyData2{
	private int content;
	private boolean available=false;
	public synchronized void put(int value){
		while(available==true){
			try{
				wait();
			}catch(InterruptedException e){
				
			}
		}
		this.content=value;
		available=true;
		notifyAll();
	}
	public synchronized int get(){
		while(available==false){
			try{
				wait();
			}catch(InterruptedException e){
				
			}
		}
		available=false;
		notifyAll();
		return this.content;
	}
}
/*
 * 生产者
 */
class Producer2 extends Thread{
	private MyData2 data;
	public Producer2(MyData2 data){
		this.data=data;
	}
	public void run(){
		for(int i=1;i<=5;i++){
			this.data.put(i);
			System.out.println("生产者:生成物品,编号为:"+i);
			try{
				sleep((int)(Math.random()*100));
			}catch(InterruptedException e){
				
			}
		}
	}
}

/*
 * 消费者
 */
class Consumer2 extends Thread{
	private MyData2 data;
	public Consumer2(MyData2 data){
		this.data=data;
	}
	public void run(){
		int value=0;
		for(int i=1;i<=5;i++){
			value=this.data.get();
			System.out.println("消费者:消费物品,编号为:"+value);
		}
	}
}
public class ProducerAndConsumer2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyData2 md=new MyData2();
		Producer2 p=new Producer2(md);
		Consumer2 c=new Consumer2(md);
		p.start();
		c.start();
	}
}

测试示例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值