经典的生产者与消费者模型(基于synchronized方法实现)

1、首先建仓库 WareHouse:

package threadt.producer.consumer;

/**
 * WareHouse -- 仓库
 * @author tiger
 * @Date 2017年7月27日
 */
class WareHouse {
	//记录仓库的库存状态,需要增加库存是设置为:true。
	boolean  state = true;
	//货物总数量
	int count = 0;
	//判断仓库是否满
	public boolean isFull(){
		return count == 20;//定义库存为20。
	}
	//判断仓库是否空
	public boolean isEmpty(){
		return count == 0;
	}
	/**
	 * 生产货物
	 * @param id 货物id
	 * @param name 货物生产机器型号
	 */
	public synchronized void producer(int id,String name){
		if (state) {
			//判断仓库库存是否满
			if (!isFull()) {
				count ++;
				System.out.println(name+" 生产货物 ["+id+"],现在货物数量" + count);
			}else {
				//满就切换为销售状态
				state = false;
				//state一为false,就唤醒销售员
				this.notifyAll();
			}
		}else {//满就休息
			try {this.wait();} 
			catch (InterruptedException e) {}
		}
	}
	/**
	 * 销售货物
	 * @param name 销售员名称
	 */
	public synchronized void sale(String name){
		//这里的state是接 producer 留下的,已经切换为 false 状态。
		if (!state) {
			//判断是否有货,只要库存不是0 就可以出售产品
			if (!isEmpty()) {
				count --;
				System.out.println(name+" 卖掉一个货物,现在货物数量" + count);
			}else {
				//空切换为制作
				state = true;
				//state一为true,就唤醒生产者,这里生产者可以有多个。
				this.notifyAll();
			}
		}else {
			System.out.println(name+ "在等待货物生产中。。。。");
			try {
				this.wait();
			} 
			catch (InterruptedException e) {}
		}
	}
}

2、接着引入生产设备Producer(生产者):持有仓库的引用,因为要向仓库中添加货物。

package threadt.producer.consumer;

import java.util.concurrent.TimeUnit;
/**
 * 生产者
 * @author tiger
 * @Date 2017年7月28日
 */
class Producer implements Runnable{
	//持有仓库的引用,因为要向仓库中添加货物。
	WareHouse ware;
	public Producer(WareHouse ware) {
		this.ware = ware;
	}
	
	public void productGoods(){
		//货物ID
		int id = (int) (Math.random()*1000);
		//生产者名称
		String name = Thread.currentThread().getName();
		//生产货物
		this.ware.producer(id, name);
	}
	@Override
	public void run() {
		//仓库只要没有满就一直不停在生产货物
		while (true) {
			productGoods();
			//模拟每个货物生产需要花费的时间
			try {
				TimeUnit.MICROSECONDS.sleep(5000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

3、引入销售员Salesman(消费者):持有仓库的引用,因为需要从仓库里取出货物取卖。

package threadt.producer.consumer;

import java.util.concurrent.TimeUnit;
/**
 * 销售员
 * @author tiger
 * @Date 2017年7月27日
 */
class Salesman implements Runnable{
	//持有仓库的引用,因为需要从仓库里取出货物取卖。
	WareHouse ware;
	
	public Salesman(WareHouse ware) {
		this.ware = ware;
	}
	
	public void sellGoods(){
		String name = Thread.currentThread().getName();
		this.ware.sale(name);
	}
	
	@Override
	public void run() {
		//仓库只要有货物就一直不停卖
		while (true) {
			sellGoods();
			//模拟卖一个货物所需要花费的时间
			try {
				TimeUnit.MICROSECONDS.sleep(50);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	} 
}
4、测试上边的模型运行状态 ProducerAndConsumerTest:创建 2 台机器(线程),4 个销售员(线程)。

package threadt.producer.consumer;
/**
 * 经典的生产者与消费者模型
 * @author tiger
 * @Date 2017年7月27日
 */
public class ProducerAndConsumerTest {
	public static void main(String[] args) throws InterruptedException {
		WareHouse shop = new WareHouse();
		Producer pro1 = new Producer(shop);
		Producer pro2 = new Producer(shop);
		Salesman con = new Salesman(shop);
		Thread make1 = new Thread(pro1,"1号生产机器");//生产者线程 1 号
		Thread make2 = new Thread(pro2,"2号生产机器");//生产者线程 2 号
		Thread cons1 = new Thread(con,"老鼠销售员1");//销售员线程1
		Thread cons2 = new Thread(con,"老虎销售员2");//销售员线程2
		Thread cons3 = new Thread(con,"蓝猫销售员3");//销售员线程3
		Thread cons4 = new Thread(con,"兔子销售员4");//销售员线程4
		Thread cons5 = new Thread(con,"小红销售员5");//销售员线程5
		make1.start();
		make2.start();
		cons1.start();
		cons2.start();
		cons3.start();
		cons4.start();
		cons5.start();
	}
}

5、运行结果片段:每次运行结果都有所差别,仓库货物总数量不会超过设定的20,有货物时,销售员才能卖,货物不满时,生产机器立马争取进入生产状态。

老虎销售员2在等待货物生产中。。。。
兔子销售员4在等待货物生产中。。。。
老鼠销售员1在等待货物生产中。。。。
蓝猫销售员3在等待货物生产中。。。。
1号生产机器 生产货物 [73],现在货物数量1
小红销售员5在等待货物生产中。。。。
2号生产机器 生产货物 [210],现在货物数量2
2号生产机器 生产货物 [354],现在货物数量3
1号生产机器 生产货物 [382],现在货物数量4
1号生产机器 生产货物 [434],现在货物数量5
2号生产机器 生产货物 [39],现在货物数量6
1号生产机器 生产货物 [526],现在货物数量7
2号生产机器 生产货物 [662],现在货物数量8
1号生产机器 生产货物 [948],现在货物数量9
2号生产机器 生产货物 [387],现在货物数量10
2号生产机器 生产货物 [981],现在货物数量11
1号生产机器 生产货物 [637],现在货物数量12
2号生产机器 生产货物 [610],现在货物数量13
1号生产机器 生产货物 [897],现在货物数量14
2号生产机器 生产货物 [177],现在货物数量15
1号生产机器 生产货物 [447],现在货物数量16
2号生产机器 生产货物 [880],现在货物数量17
1号生产机器 生产货物 [27],现在货物数量18
1号生产机器 生产货物 [71],现在货物数量19
2号生产机器 生产货物 [160],现在货物数量20
蓝猫销售员3 卖掉一个货物,现在货物数量19
老鼠销售员1 卖掉一个货物,现在货物数量18
老虎销售员2 卖掉一个货物,现在货物数量17
兔子销售员4 卖掉一个货物,现在货物数量16
小红销售员5 卖掉一个货物,现在货物数量15
老鼠销售员1 卖掉一个货物,现在货物数量14
兔子销售员4 卖掉一个货物,现在货物数量13
老虎销售员2 卖掉一个货物,现在货物数量12
小红销售员5 卖掉一个货物,现在货物数量11
蓝猫销售员3 卖掉一个货物,现在货物数量10
老鼠销售员1 卖掉一个货物,现在货物数量9
兔子销售员4 卖掉一个货物,现在货物数量8
老虎销售员2 卖掉一个货物,现在货物数量7
蓝猫销售员3 卖掉一个货物,现在货物数量6
小红销售员5 卖掉一个货物,现在货物数量5
老鼠销售员1 卖掉一个货物,现在货物数量4
小红销售员5 卖掉一个货物,现在货物数量3
蓝猫销售员3 卖掉一个货物,现在货物数量2
老虎销售员2 卖掉一个货物,现在货物数量1
兔子销售员4 卖掉一个货物,现在货物数量0
兔子销售员4在等待货物生产中。。。。
老鼠销售员1在等待货物生产中。。。。
小红销售员5在等待货物生产中。。。。
蓝猫销售员3在等待货物生产中。。。。
老虎销售员2在等待货物生产中。。。。
1号生产机器 生产货物 [166],现在货物数量1
2号生产机器 生产货物 [950],现在货物数量2
2号生产机器 生产货物 [0],现在货物数量3
1号生产机器 生产货物 [170],现在货物数量4
1号生产机器 生产货物 [217],现在货物数量5
2号生产机器 生产货物 [32],现在货物数量6
2号生产机器 生产货物 [780],现在货物数量7
1号生产机器 生产货物 [440],现在货物数量8
2号生产机器 生产货物 [444],现在货物数量9
1号生产机器 生产货物 [251],现在货物数量10
1号生产机器 生产货物 [755],现在货物数量11
2号生产机器 生产货物 [887],现在货物数量12
2号生产机器 生产货物 [104],现在货物数量13
1号生产机器 生产货物 [252],现在货物数量14
1号生产机器 生产货物 [101],现在货物数量15
2号生产机器 生产货物 [726],现在货物数量16
2号生产机器 生产货物 [798],现在货物数量17
1号生产机器 生产货物 [481],现在货物数量18
1号生产机器 生产货物 [115],现在货物数量19
2号生产机器 生产货物 [751],现在货物数量20
蓝猫销售员3 卖掉一个货物,现在货物数量19
老鼠销售员1 卖掉一个货物,现在货物数量18
小红销售员5 卖掉一个货物,现在货物数量17
兔子销售员4 卖掉一个货物,现在货物数量16
老虎销售员2 卖掉一个货物,现在货物数量15
蓝猫销售员3 卖掉一个货物,现在货物数量14
老虎销售员2 卖掉一个货物,现在货物数量13
兔子销售员4 卖掉一个货物,现在货物数量12
老鼠销售员1 卖掉一个货物,现在货物数量11
小红销售员5 卖掉一个货物,现在货物数量10
蓝猫销售员3 卖掉一个货物,现在货物数量9
兔子销售员4 卖掉一个货物,现在货物数量8
老虎销售员2 卖掉一个货物,现在货物数量7
小红销售员5 卖掉一个货物,现在货物数量6
老鼠销售员1 卖掉一个货物,现在货物数量5
兔子销售员4 卖掉一个货物,现在货物数量4
老虎销售员2 卖掉一个货物,现在货物数量3
老鼠销售员1 卖掉一个货物,现在货物数量2
小红销售员5 卖掉一个货物,现在货物数量1
蓝猫销售员3 卖掉一个货物,现在货物数量0
小红销售员5在等待货物生产中。。。。
老鼠销售员1在等待货物生产中。。。。
蓝猫销售员3在等待货物生产中。。。。
老虎销售员2在等待货物生产中。。。。
兔子销售员4在等待货物生产中。。。。
1号生产机器 生产货物 [938],现在货物数量1
2号生产机器 生产货物 [475],现在货物数量2


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ljt-tiger

thanks

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值