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、此時(shí)對(duì)象調(diào)用它的喚醒方法notify(),意思是這個(gè)同步塊執(zhí)行完后它要釋放鎖,把鎖交給等待a資源的線程;
2、輸出1;
3、該對(duì)象執(zhí)行等待方法,意思是此時(shí)此刻起擁有這個(gè)對(duì)象鎖的線程(也就是這里的1號(hào)線程)釋放CPU控制權(quán),釋放鎖,并且線程進(jìn)入阻塞狀態(tài),后面的代碼暫時(shí)不執(zhí)行,因未執(zhí)行完同步塊,所以1也沒(méi)起作用;
4、在這之前的某時(shí)刻線程2運(yùn)行run方法,但苦于沒(méi)有獲得a對(duì)象的鎖,所以無(wú)法繼續(xù)運(yùn)行,但3步驟之后,它獲得了a的鎖,此時(shí)執(zhí)行a的喚醒方法notify(),同理,意思是這個(gè)同步塊執(zhí)行完后它要釋放鎖,把鎖交給等待a資源的線程;
5、輸出2;
6、執(zhí)行a的等待方法,意思是此時(shí)此刻起擁有這個(gè)對(duì)象鎖的線程(也就是這里的2號(hào)線程)釋放CPU控制權(quán),釋放鎖,并且線程進(jìn)入阻塞狀態(tài),后面的代碼暫時(shí)不執(zhí)行,因未執(zhí)行完同步塊,所以2號(hào)線程的4步驟的喚醒方法也沒(méi)起作用;
7、此時(shí)1號(hào)線程執(zhí)行到3步驟,發(fā)現(xiàn)對(duì)象鎖沒(méi)有被使用,所以繼續(xù)執(zhí)行3步驟中wait方法后面的代碼,于是輸出:------線程1獲得鎖,wait()后的代碼繼續(xù)運(yùn)行:1;
8、此時(shí)while循環(huán)滿足條件,繼續(xù)執(zhí)行,所以,再執(zhí)行1號(hào)線程的喚醒方法,意思是這個(gè)同步塊執(zhí)行完后它要釋放鎖;
9、輸出1;
10、執(zhí)行等待方法,線程1阻塞,釋放資源鎖;
11、此時(shí)線程2又獲得了鎖,執(zhí)行到步驟6,繼續(xù)執(zhí)行wait方法后面的代碼,所以輸出:------線程2獲得鎖,wait()后的代碼繼續(xù)運(yùn)行:2;
12、繼續(xù)執(zhí)行while循環(huán),輸出2;
··· ···
上一篇有提到j(luò)oin方法實(shí)際上 是調(diào)用wait();
1)wait()、notify()和notifyAll()方法是本地方法,并且為final方法,無(wú)法被重寫。
2)調(diào)用某個(gè)對(duì)象的wait()方法能讓當(dāng)前線程阻塞,并且當(dāng)前線程必須擁有此對(duì)象的monitor(即鎖,或者叫管程)
3)調(diào)用某個(gè)對(duì)象的notify()方法能夠喚醒一個(gè)正在等待這個(gè)對(duì)象的monitor的線程,如果有多個(gè)線程都在等待這個(gè)對(duì)象的monitor,則只能喚醒其中一個(gè)線程;
4)調(diào)用notifyAll()方法能夠喚醒所有正在等待這個(gè)對(duì)象的monitor的線程;
wait()方法與notify()必須要與synchronized(resource)一起使用。也就是wait與notify針對(duì)已經(jīng)獲取了resource鎖的線程進(jìn)行操作,從語(yǔ)法角度來(lái)說(shuō)就是Obj.wait(),Obj.notify必須在synchronized(Obj){...}語(yǔ)句塊內(nèi)。從功能上來(lái)說(shuō)wait()線程在獲取對(duì)象鎖后,主動(dòng)釋放CPU控制權(quán),主動(dòng)釋放對(duì)象鎖,同時(shí)本線程休眠。直到有其它線程調(diào)用對(duì)象的notify()喚醒該線程,才能繼續(xù)獲取對(duì)象鎖,并繼續(xù)執(zhí)行。相應(yīng)的notify()就是對(duì)對(duì)象鎖的釋放操作。【因此,我們可以發(fā)現(xiàn),wait和notify方法均可釋放對(duì)象的鎖,但wait同時(shí)釋放CPU控制權(quán),即它后面的代碼停止執(zhí)行,線程進(jìn)入阻塞狀態(tài),而notify方法不立刻釋放CPU控制權(quán),而是在相應(yīng)的synchronized(){}語(yǔ)句塊執(zhí)行結(jié)束,再自動(dòng)釋放鎖。】釋放鎖后,JVM會(huì)在等待resoure的線程中選取一線程,賦予其對(duì)象鎖,喚醒線程,繼續(xù)執(zhí)行。這樣就提供了在線程間同步、喚醒的操作。Thread.sleep()與Object.wait()二者都可以暫停當(dāng)前線程,釋放CPU控制權(quán),主要的區(qū)別在于Object.wait()在釋放CPU同時(shí),釋放了對(duì)象鎖的控制,而在同步塊中的Thread.sleep()方法并不釋放鎖,僅釋放CPU控制權(quán)。
sleep 是線程類(Thread)的方法,導(dǎo)致此線程暫停執(zhí)行指定時(shí)間,給執(zhí)行機(jī)會(huì)給其他線程,但是監(jiān)控狀態(tài)依然保持,到時(shí)后會(huì)自動(dòng)恢復(fù)。調(diào)用sleep 不會(huì)釋放對(duì)象鎖。wait 是Object 類的方法,對(duì)此對(duì)象調(diào)用wait 方法導(dǎo)致本線程放棄對(duì)象鎖,進(jìn)入等待此對(duì)象的等待鎖定池,只有針對(duì)此對(duì)象發(fā)出notify 方法(或notifyAll)后本線程才進(jìn)入對(duì)象鎖定池準(zhǔn)備獲得對(duì)象鎖進(jìn)入運(yùn)行狀態(tài)。
1、這兩個(gè)方法來(lái)自不同的類分別是Thread和Object2、最主要是sleep方法沒(méi)有釋放鎖,而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類中方法,表示讓一個(gè)線程進(jìn)入睡眠狀態(tài),等待一定的時(shí)間之后,自動(dòng)醒來(lái)進(jìn)入到可運(yùn)行狀態(tài),不會(huì)馬上進(jìn)入運(yùn)行狀態(tài),因?yàn)榫€程調(diào)度機(jī)制恢復(fù)線程的運(yùn)行也需要時(shí)間,一個(gè)線程對(duì)象調(diào)用了sleep方法之后,并不會(huì)釋放他所持有的所有對(duì)象鎖,所以也就不會(huì)影響其他進(jìn)程對(duì)象的運(yùn)行。但在sleep的過(guò)程中過(guò)程中有可能被其他對(duì)象調(diào)用它的interrupt(),產(chǎn)生InterruptedException異常,如果你的程序不捕獲這個(gè)異常,線程就會(huì)異常終止,進(jìn)入TERMINATED狀態(tài),如果你的程序捕獲了這個(gè)異常,那么程序就會(huì)繼續(xù)執(zhí)行catch語(yǔ)句塊(可能還有finally語(yǔ)句塊)以及以后的代碼。
注意sleep()方法是一個(gè)靜態(tài)方法,也就是說(shuō)他只對(duì)當(dāng)前對(duì)象有效,通過(guò)t.sleep()讓t對(duì)象進(jìn)入sleep,這樣的做法是錯(cuò)誤的,它只會(huì)是使當(dāng)前線程被sleep 而不是t線程
wait屬于Object的成員方法,一旦一個(gè)對(duì)象調(diào)用了wait方法,必須要采用notify()和notifyAll()方法喚醒該進(jìn)程;如果線程擁有某個(gè)或某些對(duì)象的同步鎖,那么在調(diào)用了wait()后,這個(gè)線程就會(huì)釋放它持有的所有同步資源,而不限于這個(gè)被調(diào)用了wait()方法的對(duì)象。wait()方法也同樣會(huì)在wait的過(guò)程中有可能被其他對(duì)象調(diào)用interrupt()方法而產(chǎn)生
總結(jié)
以上是生活随笔為你收集整理的java多线程notify_Java多线程 wait notify的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java分页查询oracle_Java中
- 下一篇: java实现套接字网络编程_Java网络