等待喚醒機制其實就是經典的“生產者與消費者”的問題。
就拿生產包子消費包子來說等待喚醒機制如何有效利用資源:
包子鋪線程生產包子,吃貨線程消費包子。當包子沒有時(包子狀態爲false),吃貨線程等待,包子鋪線程生產包子(即包子狀態爲true),並通知吃貨線程(解除吃貨的等待狀態),因爲已經有包子了,那麼包子鋪線程進入等待狀態。接下來,吃貨線程能否進一步執行則取決於鎖的獲取情況。如果吃貨獲取到鎖,那麼就執行吃包子動作,包子吃完(包子狀態爲false),並通知包子鋪線程(解除包子鋪的等待狀態),吃貨線程進入等待。包子鋪線程能否進一步執行則取決於鎖的獲取情況。
代碼演示:
包子資源類:
public class BaoZi {
String pier ;
String xianer ;
boolean flag = false ;//包子資源 是否存在 包子資源狀態
}
吃貨線程類:
public class ChiHuo extends Thread {
private BaoZi bz;
public ChiHuo(BaoZi bz) {
this.bz = bz;
}
@Override
public void run() {
synchronized (bz) {
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (bz.flag == false) {//沒包子
try {
bz.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("吃貨正在吃" + bz.pier + bz.xianer + "包子");
bz.flag = false;
bz.notify();
}
}
}
}
包子鋪線程類:
public class BaoZiPu extends Thread {
private BaoZi bz;
public BaoZiPu(BaoZi bz) {
this.bz = bz;
}
@Override
public void run() {
int count = 0;
//同步
synchronized (bz) {
//造包子
while (true) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (bz.flag == true) {//包子資源 存在
try {
bz.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 沒有包子 造包子
System.out.println("包子鋪開始做包子");
if (count % 2 == 0) {
// 冰皮 五仁
bz.pier = "冰皮";
bz.xianer = "五仁";
} else {
// 薄皮 牛肉大蔥
bz.pier = "薄皮";
bz.xianer = "牛肉大蔥";
}
count++;
bz.flag = true;
System.out.println("包子造好了:" + bz.pier + bz.xianer);
System.out.println("吃貨來吃吧");
//喚醒等待線程 (吃貨)
bz.notify();
}
}
}
}
測試類:
public class Test {
public static void main(String[] args) {
//等待喚醒案例
BaoZi bz = new BaoZi();
ChiHuo ch = new ChiHuo(bz);
ch.setName("吃貨");
BaoZiPu bzp = new BaoZiPu(bz);
bzp.setName("包子鋪");
ch.start();
bzp.start();
}
}
執行效果:
包子鋪開始做包子
包子造好了:冰皮五仁
吃貨來吃吧
吃貨正在吃冰皮五仁包子
包子鋪開始做包子
包子造好了:薄皮牛肉大蔥
吃貨來吃吧
吃貨正在吃薄皮牛肉大蔥包子
包子鋪開始做包子
包子造好了:冰皮五仁
吃貨來吃吧
吃貨正在吃冰皮五仁包子
包子鋪開始做包子
包子造好了:薄皮牛肉大蔥
吃貨來吃吧
吃貨正在吃薄皮牛肉大蔥包子
包子鋪開始做包子
包子造好了:冰皮五仁
吃貨來吃吧
吃貨正在吃冰皮五仁包子
包子鋪開始做包子
包子造好了:薄皮牛肉大蔥
吃貨來吃吧
吃貨正在吃薄皮牛肉大蔥包子
包子鋪開始做包子
包子造好了:冰皮五仁
吃貨來吃吧
吃貨正在吃冰皮五仁包子
包子鋪開始做包子
包子造好了:薄皮牛肉大蔥
吃貨來吃吧
Process finished with exit code -1