目录
代码片段
一、产品实体类(代码:产品经理)
* @author eddie.lee
* @ClassName Product
* @description 产品POJO类
* @modified by
*/
public class Product {
private Integer id;
public Product(Integer id) {
this.id = id;
}
@Override
public String toString() {
return "Product{" +
"id=" + id +
'}';
}
}
二、存储产品类 (代号:公司)
public class Storage {
private List<Product> list = new ArrayList<>();
public synchronized void pop() {
if (list.isEmpty()) {
System.out.println("仓库已经清空,等待下一批生成");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notifyAll();
Product product = list.get(0);
list.remove(product);
System.out.println(" --> 产品出库:" + product);
}
public synchronized void push(Product producedProduct) {
int maxSize = 5;
if (list.size() >= maxSize) {
System.out.println("仓库已经满啦,没地方放了,快停止生产吧,通知消费者来消费");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notifyAll();
list.add(producedProduct);
System.out.println(" <-- 产品入库:" + producedProduct);
}
}
三、生产者(代号:程序员)
public class Producer implements Runnable {
private Storage storage;
public Producer(Storage storage) {
this.storage = storage;
}
@Override
public void run() {
int num = 10;
for (int i = 0; i < num; i++) {
Product product = new Product(i);
storage.push(product);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
三、消费者(代号:销售)
public class Consumer implements Runnable {
private Storage storage;
public Consumer(Storage storage) {
this.storage = storage;
}
@Override
public void run() {
int num = 10;
for (int i = 0; i < num; i++) {
storage.pop();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
四、入口(代号:客户)
public class Controller {
public static void main(String[] args) {
Storage storage = new Storage();
Producer producer = new Producer(storage);
Consumer consumer = new Consumer(storage);
new Thread(producer).start();
new Thread(consumer).start();
}
}
五、打印日志(代号:流水清单)
仓库已经清空,等待下一批生成
<-- 产品入库:Product{id=0}
--> 产品出库:Product{id=0}
<-- 产品入库:Product{id=1}
--> 产品出库:Product{id=1}
仓库已经清空,等待下一批生成
<-- 产品入库:Product{id=2}
--> 产品出库:Product{id=2}
仓库已经清空,等待下一批生成
<-- 产品入库:Product{id=3}
--> 产品出库:Product{id=3}
仓库已经清空,等待下一批生成
<-- 产品入库:Product{id=4}
--> 产品出库:Product{id=4}
<-- 产品入库:Product{id=5}
--> 产品出库:Product{id=5}
仓库已经清空,等待下一批生成
<-- 产品入库:Product{id=6}
--> 产品出库:Product{id=6}
仓库已经清空,等待下一批生成
<-- 产品入库:Product{id=7}
--> 产品出库:Product{id=7}
仓库已经清空,等待下一批生成
<-- 产品入库:Product{id=8}
--> 产品出库:Product{id=8}
仓库已经清空,等待下一批生成
<-- 产品入库:Product{id=9}
--> 产品出库:Product{id=9}
说明
- wait()使用必需在synchronized包括内,wait()会让synchronized的线程暂时停止运行,释放锁并且失去控制权。
- notifyAll()来唤醒正在wait的线程,让任务继续往下走
- 生产者与消费者共用一个Storage里面的集合
- 仓库集合空了,消费者就会调用wait()方法暂停线程,让生产者notifyAll唤醒线程,直到仓库满载情况下,进入wait(),让消费者再次notifyAll唤醒线程去消费。