恭喜辛勤的鱼摊主今日生意火热,瞬间就售空掉捕捞到的鱼。
这里我们把卖鱼当作产出方,顾客当作消费方,其实就是个生产与消费的例子。而生产与消费无处不在,工厂生产玩偶,消费者购买玩偶;餐厅里厨师炒菜,食客吃菜;市场买菜的阿姨卖菜,妈妈们去买菜等等。
假若生产的商品放置于仓库(鱼摊主捕鱼将鱼放置于鱼篓),那么仓库(鱼篓)肯定有个上限,而当仓库无商品(鱼篓无鱼)时候,消费者也无处消费。
我们又如何确保,仓库(鱼篓)满的时候生产者(鱼摊主)停止生产(捕鱼)直到仓库(鱼篓)可以继续存放商品(鱼),仓库(鱼篓)空的时候消费者停止消费直到仓库(鱼篓)又库存(有鱼)?
生产者和消费者是两个独立的并发事件,生产者(鱼摊主他老婆也去捕鱼啦!)生产商品的同时消费者也可能在消费商品。
生产与消费是多线程的经典例子之一,主要涉及到
1.线程等待唤醒
2.同步锁机制
那么我们来看看代码是如何现实的?(注释的地方请注意下)
public static class Producer implements Runnable{
private List<Object> goods;
private String name;
public Producer(List<Object> goods,String name){
this.name = name;
this.goods = goods;
}
public void product() throws InterruptedException {
synchronized (goods){//synchronized同步锁goods
while(goods.size()==10){
System.out.println(Thread.currentThread().getName()+" "+name+" "+" goods is full");
goods.wait();//线程进入等待状态,并且释放锁goods
}
//商品没有满或者处于等待状态的某生产线程唤醒后,执行以下代码
goods.add(new Object());
System.out.println(Thread.currentThread().getName()+" "+name+" product,now goods'count is "+goods.size());
goods.notifyAll();//唤醒在等待的线程
}
}
@Override
public void run() {
try {
product();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class Consumer implements Runnable{
private List<Object> goods;
private String name;
public Consumer(List<Object> goods,String name){
this.name = name;
this.goods = goods;
}
public void consume() throws InterruptedException {
synchronized (goods){//synchronized同步锁goods
while(goods.size()==0){
System.out.println(Thread.currentThread().getName()+" "+name+" "+" goods is empty");
goods.wait();//线程进入等待状态,释放锁goods;
}
//商品没有空或者处于等待状态的某消费线程唤醒后,执行以下代码
goods.remove(0);
System.out.println(Thread.currentThread().getName()+" "+name+" consume,now goods'count is "+goods.size());
goods.notifyAll();//唤醒在等待的线程
}
}
@Override
public void run() {
try {
consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
输出结果(结果顺序不一定相同)
Thread-0 Producer1 product,now goods'count is 1
Thread-1 Consumer1 consume,now goods'count is 0
Thread-2 Consumer2 goods is empty
Thread-3 Consumer3 goods is empty
Thread-4 Producer2 product,now goods'count is 1
Thread-3 Consumer3 consume,now goods'count is 0
Thread-2 Consumer2 goods is empty
本文就只用这个wait/notifyAll来实现生产与消费,但其实还有很多种实现方式,大家可以自己思考下。
从这个多线程经典例子中可以学习到很多有趣的或者你忽略的点。
谢谢大家观阅!
本人公众号程序员七猫,不定期更新!
感谢您的喜欢
请多多关注和支持!