歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Java 線程協作 wait(等待)與 notiy(通知)

一.wait()、notify()和notifyAll()

為了更好的支持多線程之間的協作,JDK提供了三個重要的本地方法

//調用某個對象的wait()方法能讓當前線程阻塞,並且當前線程必須擁有此對象的鎖.
 public final void wait() throws InterruptedException {
        wait(0);
    }
//調用某個對象的notify()方法能夠喚醒一個正在等待這個對象的鎖的線程,如果有多個線程都在等待這個對象的鎖,則只能喚醒其中一個線程
 public final native void notify();
//notifyAll()方法能夠喚醒所有正在等待這個對象鎖的線程;
 public final native void notifyAll();

如圖:當一個擁有Object鎖的線程調用 wait()方法時,就會使當前線程加入object.wait 等待隊列中,並且釋放當前占用的Object鎖,這樣其他線程就有機會獲取這個Object鎖,獲得Object鎖的線程調用notify()方法,就能在Object.wait 等待隊列中隨機喚醒一個線程(該喚醒是隨機的與加入的順序無關,優先級高的被喚醒概率會高),若果調用notifyAll()方法就喚醒全部的線程。注意:調用notify()方法後並不會立即釋放object鎖,會等待該線程執行完畢後釋放Object鎖。

代碼:

public class WaitTest {
    private static Object object=new Object();
    public static void main(String[] args) {
        Thread thread=new Thread(){
            @Override
            public void run() {
                synchronized (object) {
                    System.out.println(System.currentTimeMillis()+":"+Thread.currentThread().getName()+"進入啟動");
                    try {
                        object.wait();//使當前線程進入等待(進入Object.wait隊列)並釋放對象鎖
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(System.currentTimeMillis()+":"+Thread.currentThread().getName()+"線程執行結束");
                }
            }
        };
        thread.start();
      Thread thread_2=new Thread(){
            @Override
            public void run() {
                synchronized (object) {
                    System.out.println(System.currentTimeMillis()+":"+Thread.currentThread().getName()+"進入啟動");
                    try {
                        object.notify();//隨機在Object.waitd隊列中喚醒一個正在等待該對象鎖的線程
                        System.out.println(System.currentTimeMillis()+":"+Thread.currentThread().getName()+"喚醒一個等待的線程");
                        Thread.sleep(10000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        thread_2.start();
    }
}

執行結果:

1473306408730:Thread-0進入啟動
1473306408731:Thread-1進入啟動
1473306408731:Thread-1喚醒一個等待的線程
1473306418731:Thread-0線程執行結束

  從時間戳中可以看出 Thread-1 在通知Thread-0 繼續執行後,Thread-0 並未立即執行,而是等待Thread-1 釋放Object鎖,在重新獲得Object鎖後,才能繼續執行。(最後兩個時間戳相減剛好是10秒)

Copyright © Linux教程網 All Rights Reserved