wait & notify
阿新 • • 發佈:2020-12-12
技術標籤:JUC
目錄
1、wait / notify 原理
- Owner執行緒發現條件不滿足,呼叫wait方法,即可進入WaitSet變為WAITING狀態
- BLOCKED和WAITING的執行緒都處於阻塞狀態,不佔用CPU時間片
- BLOCKED執行緒會在Owner執行緒釋放鎖的時候被喚醒
- WAITING執行緒會在Owner執行緒呼叫notify或notifyAll時喚醒,但喚醒後並不意味著立刻獲得鎖,仍需進入EntryList重新競爭
2、API介紹
-
obj.wait()讓進入object監視器的執行緒到waitSet等待
-
obj.notify()在object上正在waitSet’等待的執行緒中挑一個喚醒
-
obj.notifyAll()讓object上正在waitSet等待的執行緒全部喚醒
他們都是執行緒之間協作的手段,都屬於Object的方法。必須獲得物件的鎖,才能呼叫這幾個方法
當沒有鎖時,丟擲異常
public class WaitAndNotify {
static final Object Lock = new Object();
public static void main(String[] args) {
try {
Lock. wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
正確姿勢
public class WaitAndNotify {
static final Object Lock = new Object();
public static void main(String[] args) {
synchronized (Lock) {
try {
Lock.wait ();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
3、練習
package com.sharing_model.wait_notify;
/**
* wait notify 正確使用
*/
public class WaitAndNotifyTrueUse {
static final Object room = new Object();
static boolean hasCigarette = false;
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
System.out.println("有煙沒?" + hasCigarette);
synchronized (room) {
if (!hasCigarette) {
System.out.println(" 沒煙,小南先休息一會!");
try {
room.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("有煙沒?" + hasCigarette);
if (hasCigarette) {
System.out.println("小南開始幹活了");
}
}
}, "小南").start();
for (int i = 0 ; i < 5 ; i++) {
new Thread(() -> {
synchronized (room) {
System.out.println("其它人開始幹活了");
}
},"其它人").start();
}
Thread.sleep(1);
new Thread(() -> {
synchronized (room) {
System.out.println("有煙了");
hasCigarette = true;
room.notify();
}
}).start();
}
}
總結:
synchronized(lock) {
while(條件不成立) {
lock.wait();
}
//幹活
}
//另一個執行緒
synchronized(lock) {
lock.notifyAll();
}