為什么 java wait/notify 必須與 synchronized 一起使用,jvm究竟做了些什么


這個課題提出來的是原先的線程並發解決的思路。目前解決線程並發,可以是lock接口結合condition  並發問題一直以來就是線程必不可少的話題。

java 是第一個內置對多線程支持的主流編程語言。在Java5之前,對多線程的支持主要是通過對塊結構的同步實現的(synchronized配合wait,notify,notifyAll),Java5引入了java.util.concurrent包,提供了對多線程編程的更高層的支持。

今天我們來說說。java中,線程提供我們解決並發。同步的方法

  通常可以使用synchronized和notify,notifyAll以及wait方法來實現線程之間的數據傳遞及控制。對於對象obj來說:

  • obj.wait():該方法的調用,使得調用該方法的執行線程(T1)放棄obj的對象鎖並阻塞,直到別的線程調用了obj的notifyAll方法、或者別的線程調用了obj的notify方法且JVM選擇喚醒(T1),被喚醒的線程(T1)依舊阻塞在wait方法中,與其它的線程一起爭奪obj的對象鎖,直到它再次獲得了obj的對象鎖之后,才能從wait方法中返回。(除了notify方法,wait還有帶有時間參數的版本,在等待了超過所設時間之后,T1線程一樣會被喚醒,進入到爭奪obj對象鎖的行列;另外中斷可以直接跳出wait方法)
  • obj.notify():該方法的調用,會從所有正在等待obj對象鎖的線程中,喚醒其中的一個(選擇算法依賴於不同實現),被喚醒的線程此時加入到了obj對象鎖的爭奪之中,然而該notify方法的執行線程此時並未釋放obj的對象鎖,而是離開synchronized代碼塊時釋放。因此在notify方法之后,synchronized代碼塊結束之前,所有其他被喚醒的,等待obj對象鎖的線程依舊被阻塞。
  • obj.notifyAll():與notify的區別是,該方法會喚醒所有正在等待obj對象鎖的線程。(不過同一時刻,也只有一個線程可以擁有obj的對象鎖)

要注意的是,wai,notify以及notifyAll方法的調用必須在相應的synchronized代碼塊之中

線程就是程序執行的路徑。多線程,也就不難理解了,程序執行的多條路徑,它們獨立執行,但是又有莫大的聯系

wait/notify字面意思是等待和告知

package com.huojg.test;

public class ThreadA {
    public static void main(String[] args) {
        ThreadB b = new ThreadB();
        b.start();// 主線程中啟動另外一個線程
        System.out.println("b is start....");
        // 括號里的b是什么意思,應該很好理解吧
        synchronized (b) {
            try {
                System.out.println("Waiting for b to complete...");
                b.wait();// 這一句是什么意思,究竟誰等待?
                System.out.println("ThreadB is Completed. Now back to main thread");
            } catch (InterruptedException e) {
            }

        }
        System.out.println("Total is :" + b.total);
    }
}

class ThreadB extends Thread {
    int total;

    public void run() {
        synchronized (this) {
            System.out.println("ThreadB is running..");
            for (int i = 0; i <= 100; i++) {
                total += i;
            }
            System.out.println("total is" + total);
            notify();
        }
    }
}
b is start....
ThreadB is running..
total is5050
Waiting for b to complete...
ThreadB is Completed. Now back to main thread
Total is :5050

 

從程序運行的結果來看就不難理解wait/notify了,wait是讓使用wait方法的對象等待,暫時先把對象鎖給讓出來,給其它持有該鎖的對象用,其它對象用完后再告知(notify)等待的那個對象可以繼續執行了,整個過程就是這樣。wait/notify主要用於一個線程要等待另一個線程執行完后,然后得到執行結果的情況。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM