并发基础学习(简单生产者消费者案例)
案例要求
1、生产者生产一个面包消费者买一个
2、初始面包0个
3、每个生产者消费者循环10次
package cc.xuhao.demo;
public class ProducerAndCustomer {
public static void main(String[] args) {
Bakery bakery = new Bakery();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
bakery.makeBread();
}
}, "灰灰").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
bakery.sellBread();
}
}, "小黑").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
bakery.makeBread();
}
}, "猪猪").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
bakery.sellBread();
}
}, "浩哥").start();
}
}
class Bakery {
private int breadNum = 0;
public synchronized void makeBread() {
try {
// 判断 (使用while防止虚假唤醒)
while (breadNum > 0) {
this.wait();
}
// 干活
System.out.println("当前面包还有" + breadNum + " " + Thread.currentThread().getName() + "生产了1个,现在有" + (++breadNum));
// 通知
this.notifyAll();;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void sellBread() {
try {
while (breadNum <= 0) {
this.wait();
}
System.out.println("当前面包还有" + breadNum + " " + Thread.currentThread().getName() + "买了1个,现在有" + (--breadNum));
this.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
总结
需要注意线程虚假唤醒问题,判断必须使用while循环,详见jdk文档java.lang.Object wait()方法说明