1、小故事 - 為什么需要 wait
-
由于條件不滿足(沒煙干不了活啊,等小M把煙送過來),小南不能繼續進行計算
-
-
-
于是老王單開了一間休息室(調用 wait 方法),讓小南到休息室(WaitSet)等著去了,但這時鎖釋放開,其它人可以由老王隨機安排進屋
-
直到小M將煙送來,大叫一聲 [ 你的煙到了 ] (調用 notify 方法)
-
-
小南于是可以離開休息室,重新進入競爭鎖的隊列
-
-
Owner 線程發現條件不滿足,調用 wait 方法,即可進入 WaitSet 變為 WAITING 狀態
-
BLOCKED 和 WAITING 的線程都處于阻塞狀態,不占用 CPU 時間片
-
BLOCKED 線程會在 Owner 線程釋放鎖時喚醒
-
WAITING 線程會在 Owner 線程調用 notify 或 notifyAll 時喚醒,但喚醒后并不意味者立刻獲得鎖,仍需進入 EntryList 重新競爭
3、API 介紹
-
obj.wait()
讓進入 object 監視器的線程到 waitSet 等待 -
obj.notify()
在 object 上正在 waitSet 等待的線程中挑一個喚醒 -
obj.notifyAll()
讓 object 上正在 waitSet 等待的線程全部喚醒
它們都是線程之間進行協作的手段,都屬于 Object 對象的方法。必須獲得此對象的鎖,才能調用這幾個方法,否則會報IllegalMonitorStateException
final static Object obj = new Object();
?
public static void main(String[] args) {
?
? ?new Thread(() -> {
? ? ? ?synchronized (obj) {
? ? ? ? ? ?log.debug("執行....");
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?obj.wait(); // 讓線程在obj上一直等待下去
? ? ? ? ? } catch (InterruptedException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? ? ? ?log.debug("其它代碼....");
? ? ? }
? }).start();
?
? ?new Thread(() -> {
? ? ? ?synchronized (obj) {
? ? ? ? ? ?log.debug("執行....");
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?obj.wait(); // 讓線程在obj上一直等待下去
? ? ? ? ? } catch (InterruptedException e) {
? ? ? ? ? ? ? ?e.printStackTrace();
? ? ? ? ? }
? ? ? ? ? ?log.debug("其它代碼....");
? ? ? }
? }).start();
?
? ?// 主線程兩秒后執行
? ?sleep(2);
? ?log.debug("喚醒 obj 上其它線程");
? ?synchronized (obj) {
? ? ? ?obj.notify(); // 喚醒obj上隨機一個線程
? ? ? ?// obj.notifyAll(); // 喚醒obj上所有等待線程
? }
}
notify 的一種結果
20:00:53.096 [Thread-0] c.TestWaitNotify - 執行....
20:00:53.099 [Thread-1] c.TestWaitNotify - 執行....
20:00:55.096 [main] c.TestWaitNotify - 喚醒 obj 上其它線程
20:00:55.096 [Thread-0] c.TestWaitNotify - 其它代碼....
notifyAll 的結果
19:58:15.457 [Thread-0] c.TestWaitNotify - 執行....
19:58:15.460 [Thread-1] c.TestWaitNotify - 執行....
19:58:17.456 [main] c.TestWaitNotify - 喚醒 obj 上其它線程
19:58:17.456 [Thread-1] c.TestWaitNotify - 其它代碼....
19:58:17.456 [Thread-0] c.TestWaitNotify - 其它代碼....
wait()
方法會釋放對象的鎖,進入 WaitSet 等待區,從而讓其他線程就機會獲取對象的鎖。無限制等待,直到 notify 為止
wait(long n)
有時限的等待, 到 n 毫秒后結束等待,或是被 notify