java多线程生产者—消费者模式

1、生产者仅仅在仓储未满时候生产,仓满则停止生产。
2、消费者仅仅在仓储有产品时候才能消费,仓空则等待。
3、当消费者发现仓储没产品可消费时候会通知生产者生产。
4、生产者在生产出可消费产品时候,应该通知等待的消费者去消费

使用Object的wait()/notify()方法
1.wait():当缓存区已满/已空时,生产者/消费者线程自己停止自己的执行,放弃锁,使自己处于等待状态,让其他进程执行。
2.notify():放生产者/消费者向缓存区放入/取出一个产品时,向其等待的线程发出可执行的通知,同时放弃锁,使自己处于等待状态。
这个模式有两种写法:管程法 和 信号灯法
附上代码(管程法):

package nsu.edu.one;
/**
 * 生产者消费者模式--->管程法
 * 模拟生产馒头和消费馒头
 */
public class Main {
	public static void main(String[] args) {
		Buffer buffer = new Buffer();
		new Producer_one(buffer).start();
		new Producer_one(buffer).start();
		new Consumer_one(buffer).start();
	}
}
//生产者
class Producer_one extends Thread{
	Buffer buffer;
	public Producer_one(Buffer buffer) {
		this.buffer = buffer;
	}
    public void run() {  //生产
    	int i=0;        //给馒头编号
    	while(true)
    	{
    		i++;
    		try {
				Thread.sleep(200);   //生产一个耗时0.2S
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    		System.out.println("生产第"+i+"个馒头");
    		buffer.push(new Bread(i));    
    	}
    	
    }
}
//消费者
class Consumer_one extends Thread{
	Buffer buffer;
	public Consumer_one(Buffer buffer) {
		this.buffer = buffer;
	}
    public void run() {   //消费
    	while(true)
    	{
    		try {
				Thread.sleep(200);   //消费一个耗时0.2S
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    		System.out.println("消费第"+buffer.consumption().id+"个馒头");
    		buffer.consumption();
    	}
    }
}
//缓冲区
class Buffer{
	Bread[] warehouse = new Bread[10];  //创建缓冲数组  大小为10
	int count = 0;    //计数
	//有两种操作  消费和生产
	public synchronized Bread consumption() {    //消费
		//什么时候不可以消费   
		if(count <= 0)
		{
			
			try {
				System.out.println("仓库空了,不能消费"+count);
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		//有数据可以消费
		count--;
		Bread bread = warehouse[count];
		
		//消费完了 通知生产者可以生产
		this.notifyAll();
		return bread;
	}
	public synchronized void push(Bread bread){   //生产
		//何时不能生产? 没有空间不能生产
		if(count == warehouse.length) {
			
			try {
				System.out.println("仓库满了,不能生产"+count);
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		//有空间可以生产
		warehouse[count] = bread;
		count++;
		this.notifyAll();
	}
}
//馒头
class Bread {
    int id;  //馒头编号
    public Bread(int id) {
    	this.id = id;
    }
}

附上代码(信号灯法):

/**
 * 生产者消费者模式--->信号灯法
 * 
 */
public class Main {

	public static void main(String[] args)
	{
		Signal signal = new Signal();
		new Producer_one(signal).start();
		new Consumer_one(signal).start();
	}

}
//生产者
class Producer_one extends Thread{
	Signal signal;
	String str;
	public Producer_one(Signal signal) {
		this.signal = signal;
	}
	public void run() {
			for(int i=0;i<100;i++) {
				signal.push();
			}
	}
}
//消费者
class Consumer_one extends Thread{
	Signal signal;
	String str;
	public Consumer_one(Signal signal) {
		this.signal = signal;
	}
	public void run() {
		for(int i=0;i<100;i++) {
			signal.pop();
		}
	}
}
//信号灯
class Signal{
	boolean flug = false;   //新号灯
	//存储
	public synchronized void push() {
		if(!flug) {     //如果新号灯为真,说明可以生产
			try {        //反之则等待
				this.wait();         
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		//开始生产
		System.out.println("生产");
		flug=!flug;    //生产完了,新号灯转变状态
		this.notifyAll();
	}
	//消费
	public synchronized void pop() {
		if(flug) {     //如果新号灯为真,说明需要等待
			try {       
				this.wait();         
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		//消费
		System.out.println("消费");
		flug=!flug;    //生产完了,新号灯转变状态
		this.notifyAll();
	}
}

努力呀!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值