呼叫wait,notify,sleep方法對鎖資源的處理
阿新 • • 發佈:2019-02-08
我們知道wait和sleep方法可以將一個執行緒阻塞的目的。wait是將執行緒從Running變為waiting,直到被notify或者notifyAll,才會將執行緒從waiting狀態變成Runnable狀態。sleep是在一段時間內將執行緒從Running變為waiting,時間過去之後,執行緒進入Runnable狀態。
在狀態轉換的時候,鎖資源發生什麼變化呢?
首先我們用一個demo來進行分析:
用於測試 wait 的 WaitTest.java |
public class WaitTest {
public void test(Object obj){
synchronized (obj){
try {
System.out.println("wait begin!");
obj.wait();
System.out.println("wait end!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
用於測試 notify 的 NotifyTest.java |
public class NotifyTest {
public void test(Object obj){
synchronized (obj){
System.out.println("notify begin");
obj.notify();
System.out.println("notify end");
}
}
}
用於測試 sleep 的 SleepTest.java |
public class SleepTest {
public void test(Object obj){
synchronized (obj){
try {
System.out.println("sleep begin!");
Thread.sleep(1000);
System.out.println("sleep end!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
用於對比測試的 CliTest.java |
public class CliTest {
public static void main(String[] args) {
Object lock = new Object();
new Thread(()->{
new WaitTest().test(lock);
},"Wait").start();
new Thread(()->{
new NotifyTest().test(lock);
},"Notify").start();
new Thread(()->{
new SleepTest().test(lock);
},"Sleep").start();
}
}
demo測試結果 |
我們可以根據測試結果可以知道:
1,wait方法呼叫了之後,執行緒立馬放棄了CPU資源,並沒有執行 “wait end !”
2,接著呼叫了notify方法,但是notify方法並沒有停下來,而是繼續列印了 ”notify end “,說明notify並沒有放棄CPU資源。
3,之前被wait的執行緒,剛剛notify給喚醒了,繼續執行沒有執行完的部分
4,sleep方法呼叫時,可以看到執行緒明顯有被阻塞。但是設定一過,就自己開始繼續執行。可以說明sleep方法會讓執行緒阻塞,但是並沒有放棄自己所持有的鎖,阻塞完畢後,它任然持有鎖,可以接著執行之前阻塞之後的任務。