1. 程式人生 > >呼叫wait,notify,sleep方法對鎖資源的處理

呼叫wait,notify,sleep方法對鎖資源的處理

  我們知道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方法會讓執行緒阻塞,但是並沒有放棄自己所持有的鎖,阻塞完畢後,它任然持有鎖,可以接著執行之前阻塞之後的任務。