等待喚醒機制代碼實現

包子類:

package demo06.waitAndNotify.baoZi;

/**
 * @Description: java類作用描述
 * @Author: Zhiwen.Li
 * @CreateDate: 2019/10/7 12:49
 * @UpdateUser: Zhiwen.Li
 * @UpdateDate: 2019/10/7 12:49
 * @UpdateRemark: 修改內容
 * @Version: 1.0
 */

/**
 *  資源類:包子類
 * 	設置包子的屬性
 * 		皮
 * 		陷
 * 		包子的狀態: 有 true,沒有 false
 */
public class BaoZi {
    // 皮
    String pi;
    // 餡
    String xian;
    // 包子的狀態: 有 true 沒有 false
    boolean flag = false;
}

包子鋪類:

package demo06.waitAndNotify.baoZi;

/**
 * @Description: java類作用描述
 * @Author: Zhiwen.Li
 * @CreateDate: 2019/10/7 12:52
 * @UpdateUser: Zhiwen.Li
 * @UpdateDate: 2019/10/7 12:52
 * @UpdateRemark: 修改內容
 * @Version: 1.0
 */

/**
 * 生產者(包子鋪)類:是一個線程類,可以繼承Thread
 * 	設置線程任務(run):生產包子
 * 	對包子的狀態進行判斷
 * 	true:有包子
 * 		包子鋪調用wait方法進入等待狀態
 * 	false:沒有包子
 * 		包子鋪生產包子
 * 		增加一些趣味性:交替生產兩種包子
 * 			有兩種狀態(i%2==0)
 * 		包子鋪生產好了包子
 * 		修改包子的狀態爲true有
 * 		喚醒喫貨線程,讓喫貨線程喫包子
 *
 * 	注意:
 * 	    包子鋪線程和包子線程關係-->通信(互斥)
 * 	    必須同時同步技術保證兩個線程只能有一個在執行
 * 	    鎖對象必須保證唯一,可以使用包子對象作爲鎖對象
 * 	    包子鋪類和喫貨的類就需要把包子對象作爲參數傳遞進來
 * 	        1.需要在成員位置創建一個包子變量
 * 	        2.使用帶參數構造方法,爲這個包子變量賦值
 */
public class BaoZiPu extends Thread{
    // 1.需要在成員位置創建一個包子變量
    private BaoZi bz;
    // 2.使用帶參數構造方法,爲這個包子變量賦值
    public BaoZiPu(BaoZi bz) {
        this.bz = bz;
    }

    // 設置線程任務
    @Override
    public void run() {
        // 定義數量
        int count = 0;
        while (true){
            // 必須同時同步技術保證兩個線程只能有一個在執行
            synchronized (bz){
                // 對包子的狀態進行判斷
                if (bz.flag == true){
                    // 有包子,進入等待
                    try {
                        // 包子鋪調用wait方法進入等待狀態
                        bz.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // 被喚醒後繼續生產包子
                // 交替生產兩種包子
                if (count%2 == 0){
                    // 生產 薄皮三鮮餡包子
                    bz.pi = "薄皮";
                    bz.xian = "三鮮餡";
                }else {
                    // 生產 冰皮 牛肉大蔥陷
                    bz.pi = "冰皮";
                    bz.xian = "牛肉大蔥陷";
                }
                count++;
                System.out.println("包子鋪正在生產:"+bz.pi+bz.xian+"包子");
                // 生產包子需要3秒鐘
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                // 包子鋪生產好了包子
                // 修改包子的狀態爲true有
                bz.flag = true;
                // 喚醒喫貨線程,讓喫貨線程喫包子
                bz.notify();
                System.out.println("包子鋪已經生產好了:"+bz.pi+bz.xian+"包子,喫貨可以開始吃了");
            }
        }
    }
}

喫貨類:

package demo06.waitAndNotify.baoZi;

/**
 * @Description: java類作用描述
 * @Author: Zhiwen.Li
 * @CreateDate: 2019/10/7 14:40
 * @UpdateUser: Zhiwen.Li
 * @UpdateDate: 2019/10/7 14:40
 * @UpdateRemark: 修改內容
 * @Version: 1.0
 */

/**
 * 消費者(喫貨)類:是一個線程類,可以繼承Thread
 * 	設置線程任務(run):喫包子
 * 	對包子的狀態進行判斷
 * 	false:沒有包子
 * 		喫貨調用wait方法進入等待狀態
 * 	true:有包子
 * 		喫貨喫包子
 * 		喫貨喫完包子
 * 		修改包子的狀態爲false沒有
 * 		喫貨喚醒包子鋪線程,生產包子
 */
public class ChiHuo extends Thread {
    // 1.需要在成員位置創建一個包子變量
    private BaoZi bz;

    // 2.使用帶參數構造方法,爲這個包子變量賦值
    public ChiHuo(BaoZi bz) {
        this.bz = bz;
    }
    // 設置線程任務(run):喫包子
    @Override
    public void run(){
        // 使用死循環 讓喫貨一直喫包子
        while (true){
            // 必須同時同步技術保證兩個線程只能有一個在執行
            synchronized (bz){
                // 判斷包子的狀態
                if (bz.flag == false){
                    try {
                        // 喫貨調用wait方法進入等待狀態
                        bz.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                // 被喚醒之後執行的代碼,喫包子
                System.out.println("喫貨正在喫:"+bz.pi+bz.xian+"的包子");
                // 喫貨喫完包子
                // 修改包子的狀態爲false沒有
                bz.flag = false;
                // 喫貨喚醒包子鋪線程,生產包子
                bz.notify();
                System.out.println("喫貨已經把:"+bz.pi+bz.xian+"的包子喫完了,包子鋪開始生產包子");
                System.out.println("----------------------------------------------------");
            }
        }
    }
}

測試類:

package demo06.waitAndNotify.baoZi;

/**
 * @Description: java類作用描述
 * @Author: Zhiwen.Li
 * @CreateDate: 2019/10/7 14:47
 * @UpdateUser: Zhiwen.Li
 * @UpdateDate: 2019/10/7 14:47
 * @UpdateRemark: 修改內容
 * @Version: 1.0
 */

/**
 * 測試類:
 * 	包含main方法,程序執行的入口,啓動程序
 * 	創建包子對象;
 * 	創建包子鋪線程,開啓,生產包子;
 * 	創建喫貨線程,開啓,喫包子;
 */
public class Demo {
    public static void main(String[] args) {
        //創建包子對象;
        BaoZi bz =new BaoZi();
        //創建包子鋪線程,開啓,生產包子;
        new BaoZiPu(bz).start();
        //創建喫貨線程,開啓,喫包子;
        new ChiHuo(bz).start();
    }
}

運行結果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章