程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> java 線程協作 wait(等待)與 notiy(通知),waitnotiy

java 線程協作 wait(等待)與 notiy(通知),waitnotiy

編輯:JAVA綜合教程

java 線程協作 wait(等待)與 notiy(通知),waitnotiy


一.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秒)

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved