這個課題提出來的是原先的線程並發解決的思路。目前解決線程並發,可以是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主要用於一個線程要等待另一個線程執行完后,然后得到執行結果的情況。