包子類(鎖對象)
包子鋪類(生產者)
吃貨類(消費者)
簡單描述:
剛剛開始的包子狀態是沒有(即沒有包子),所以喚醒包子鋪線程去生產包子,生產完包子後,修改包子狀態爲有,喚醒吃貨線程去吃包子,包子鋪線程進入等待狀態;吃貨吃完包子後,修改包子狀態爲沒有,喚醒包子鋪線程,吃貨線程進入等待狀態。爲了保證線程安全,使用了同步代碼塊,用包子類作爲鎖對象。
while(true){}
無限循環,讓包子鋪一直生產包子,吃貨一直吃包子。
BaoZi.java
public class BaoZi {
// 皮
String pi;
// 餡
String xian;
// 包子的狀態:有 true ,沒有 false ,設置初始值爲 false 沒有包自
boolean flag = false;
}
BaoZiPu.java
public class BaoZiPu extends Thread{
// 需要在成員位置創建一個包子變量
private BaoZi bz;
// 使用帶參數構造方法,爲這個包子變量附值
public BaoZiPu(BaoZi bz){
this.bz = bz;
}
// 設置線程任務(run):生產包子
@Override
public void run() {
// 定義一個變量
int count = 0;
while(true) {
// 必須同時同步技術保證兩個線程只能一個在執行
synchronized (bz) {
// 對包子的狀態進行判斷
if (bz.flag == true) {
// 包子鋪調用 wait 方法進入等待狀態
try {
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 + "包子,吃貨可以開始吃");
}
}
}
}
ChiHuo.java
public class ChiHuo extends Thread{
// 需要在成員位置創建一個包子變量
private BaoZi bz;
// 使用帶參數構造方法,爲這個包子變量附值
public ChiHuo(BaoZi bz){
this.bz = bz;
}
// 設置線程任務(run):吃包子
@Override
public void run() {
// 使用死循環,讓吃貨一直吃包子
while(true){
// 必須同時同步技術保證兩個線程只能一個在執行
synchronized(bz){
// 對包子的狀態進行判斷
if (bz.flag == false){
// 吃貨調用 wait 方法進入等待狀態
try {
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("-----------------------------");
}
}
}
}
DemoTest.java
public class DemoTest {
public static void main(String[] args) {
System.out.println("-------");
BaoZi bz = new BaoZi();
// 創建包子鋪線程,開啓,生產包子
new BaoZiPu(bz).start();
// 創建吃貨線程,開啓,吃包子
new ChiHuo(bz).start();
}
}