并发基础学习(简单生产者消费者案例)

852

案例要求

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()方法说明
2b11955b50c2a