java多线程notify_Java多线程 wait notify
源碼
java
public final native void notify();
public final native void notifyAll();
public final void wait() throws InterruptedException {
wait(0);
}
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos > 0) {
timeout++;
}
wait(timeout);
}
1、此時對象調用它的喚醒方法notify(),意思是這個同步塊執行完后它要釋放鎖,把鎖交給等待a資源的線程;
2、輸出1;
3、該對象執行等待方法,意思是此時此刻起擁有這個對象鎖的線程(也就是這里的1號線程)釋放CPU控制權,釋放鎖,并且線程進入阻塞狀態,后面的代碼暫時不執行,因未執行完同步塊,所以1也沒起作用;
4、在這之前的某時刻線程2運行run方法,但苦于沒有獲得a對象的鎖,所以無法繼續運行,但3步驟之后,它獲得了a的鎖,此時執行a的喚醒方法notify(),同理,意思是這個同步塊執行完后它要釋放鎖,把鎖交給等待a資源的線程;
5、輸出2;
6、執行a的等待方法,意思是此時此刻起擁有這個對象鎖的線程(也就是這里的2號線程)釋放CPU控制權,釋放鎖,并且線程進入阻塞狀態,后面的代碼暫時不執行,因未執行完同步塊,所以2號線程的4步驟的喚醒方法也沒起作用;
7、此時1號線程執行到3步驟,發現對象鎖沒有被使用,所以繼續執行3步驟中wait方法后面的代碼,于是輸出:------線程1獲得鎖,wait()后的代碼繼續運行:1;
8、此時while循環滿足條件,繼續執行,所以,再執行1號線程的喚醒方法,意思是這個同步塊執行完后它要釋放鎖;
9、輸出1;
10、執行等待方法,線程1阻塞,釋放資源鎖;
11、此時線程2又獲得了鎖,執行到步驟6,繼續執行wait方法后面的代碼,所以輸出:------線程2獲得鎖,wait()后的代碼繼續運行:2;
12、繼續執行while循環,輸出2;
··· ···
上一篇有提到join方法實際上 是調用wait();
1)wait()、notify()和notifyAll()方法是本地方法,并且為final方法,無法被重寫。
2)調用某個對象的wait()方法能讓當前線程阻塞,并且當前線程必須擁有此對象的monitor(即鎖,或者叫管程)
3)調用某個對象的notify()方法能夠喚醒一個正在等待這個對象的monitor的線程,如果有多個線程都在等待這個對象的monitor,則只能喚醒其中一個線程;
4)調用notifyAll()方法能夠喚醒所有正在等待這個對象的monitor的線程;
wait()方法與notify()必須要與synchronized(resource)一起使用。也就是wait與notify針對已經獲取了resource鎖的線程進行操作,從語法角度來說就是Obj.wait(),Obj.notify必須在synchronized(Obj){...}語句塊內。從功能上來說wait()線程在獲取對象鎖后,主動釋放CPU控制權,主動釋放對象鎖,同時本線程休眠。直到有其它線程調用對象的notify()喚醒該線程,才能繼續獲取對象鎖,并繼續執行。相應的notify()就是對對象鎖的釋放操作。【因此,我們可以發現,wait和notify方法均可釋放對象的鎖,但wait同時釋放CPU控制權,即它后面的代碼停止執行,線程進入阻塞狀態,而notify方法不立刻釋放CPU控制權,而是在相應的synchronized(){}語句塊執行結束,再自動釋放鎖。】釋放鎖后,JVM會在等待resoure的線程中選取一線程,賦予其對象鎖,喚醒線程,繼續執行。這樣就提供了在線程間同步、喚醒的操作。Thread.sleep()與Object.wait()二者都可以暫停當前線程,釋放CPU控制權,主要的區別在于Object.wait()在釋放CPU同時,釋放了對象鎖的控制,而在同步塊中的Thread.sleep()方法并不釋放鎖,僅釋放CPU控制權。
sleep 是線程類(Thread)的方法,導致此線程暫停執行指定時間,給執行機會給其他線程,但是監控狀態依然保持,到時后會自動恢復。調用sleep 不會釋放對象鎖。wait 是Object 類的方法,對此對象調用wait 方法導致本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象發出notify 方法(或notifyAll)后本線程才進入對象鎖定池準備獲得對象鎖進入運行狀態。
1、這兩個方法來自不同的類分別是Thread和Object2、最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他線程可以使用同步控制塊或者方法。3、wait,notify和notifyAll只能在同步控制方法或者同步控制塊里面使用,而sleep可以在任何地方使用(使用范圍)
[](http://blog.csdn.net/congqingbin/article/details/7871862)[](http://blog.csdn.net/congqingbin/article/details/7871862)synchronized(x){
x.notify()
//或者wait()
}
4、sleep必須捕獲異常,而wait,notify和notifyAll不需要捕獲異常
sleep方法屬于Thread類中方法,表示讓一個線程進入睡眠狀態,等待一定的時間之后,自動醒來進入到可運行狀態,不會馬上進入運行狀態,因為線程調度機制恢復線程的運行也需要時間,一個線程對象調用了sleep方法之后,并不會釋放他所持有的所有對象鎖,所以也就不會影響其他進程對象的運行。但在sleep的過程中過程中有可能被其他對象調用它的interrupt(),產生InterruptedException異常,如果你的程序不捕獲這個異常,線程就會異常終止,進入TERMINATED狀態,如果你的程序捕獲了這個異常,那么程序就會繼續執行catch語句塊(可能還有finally語句塊)以及以后的代碼。
注意sleep()方法是一個靜態方法,也就是說他只對當前對象有效,通過t.sleep()讓t對象進入sleep,這樣的做法是錯誤的,它只會是使當前線程被sleep 而不是t線程
wait屬于Object的成員方法,一旦一個對象調用了wait方法,必須要采用notify()和notifyAll()方法喚醒該進程;如果線程擁有某個或某些對象的同步鎖,那么在調用了wait()后,這個線程就會釋放它持有的所有同步資源,而不限于這個被調用了wait()方法的對象。wait()方法也同樣會在wait的過程中有可能被其他對象調用interrupt()方法而產生
總結
以上是生活随笔為你收集整理的java多线程notify_Java多线程 wait notify的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java分页查询oracle_Java中
- 下一篇: java系统的标准输出对象_到了宋代,虽