JAVA基础--多线程及线程安全案例 等待与唤醒(生产者与 消费者)

等待与唤醒案例

综合使用线程的条件对象和同步代码块来实现线程安全。
以买卖包子为案例,顾客买包子,有则直接吃,没有包子则需等待制作包子,包子铺中有顾客需要包子并且包子库没包子则需制作,没顾客需要包子不制作包子。
在这里插入图片描述
很明显有顾客线程以及包子铺线程,通过同步代码块对两个线程实现同步控制。
包子类,设置包子的属性
BaoZi.java
get、set方法已省略

public class BaoZi {
    
    
    private String pi;
    private String xian;
    private Boolean state;

    public BaoZi(String pi, String xian, Boolean state) {
    
    
        this.pi = pi;
        this.xian = xian;
        this.state = state;
    }

    public BaoZi() {
    
    
    }
}

包子铺类,生产包子

public class BaoZiPu extends Thread{
    
    
    private BaoZi bz;
    private int count=0;

    public BaoZiPu(BaoZi bz) {
    
    
        this.bz = bz;
    }

    @Override
    public void run() {
    
    
        // 一直生产包子
        while(true) {
    
    
            // 利用同步代码块来实现和吃货线程间的同步
            synchronized (bz) {
    
    
                // 如果有包子,进入等待状态
                if (bz.getState()) {
    
    
                    try {
    
    
                        bz.wait();
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                } else {
    
    
                    // 没包子,生产包子
                    // 生产两种口味的包子
                    if(count%2==0) {
    
    
                        // 生产大葱韭菜陷包子
                        bz.setPi("薄皮");
                        bz.setXian("大葱韭菜");
                    } else {
    
    
                        // 生产腰子卤肉陷包子
                        bz.setPi("厚皮");
                        bz.setXian("腰子卤肉");
                    }
                    System.out.println("顾客,您的"+bz.getPi()+bz.getXian()+"包子正在制作");
                    try {
    
    
                        sleep(3000);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                    System.out.println("您的"+bz.getPi()+bz.getXian()+"包子已经做好");
                    count++;
                    // 将包子状态设置为true
                    bz.setState(true);
                    // 唤醒吃货线程吃包子
                    bz.notifyAll();
                }
            }
        }
    }
}

顾客类,吃包子

public class ChiHuo extends Thread{
    
    
    private BaoZi bz;

    public ChiHuo(BaoZi bz) {
    
    
        this.bz = bz;
    }

    @Override
    public void run() {
    
    
        while(true) {
    
    
            synchronized (bz) {
    
    
                if (bz.getState()) {
    
    
                    // 有包子,开吃
                    System.out.println("开始吃包子");
                    bz.setState(false);
                    bz.notifyAll();
                } else {
    
    
                    // 没包子,等待状态
                    try {
    
    
                        bz.wait();
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

测试类,开启线程

public class DemoTest {
    
    

    public static void main(String[] args) {
    
    
        BaoZi baoZi = new BaoZi("第一个皮","第一个陷",true);
        BaoZiPu bzp = new BaoZiPu(baoZi);
        bzp.start();
        ChiHuo ch = new ChiHuo(baoZi);
        ch.start();
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44660367/article/details/109145319