Java線程之sleep與wait的區別

sleep()方法

sleep()使當前線程進入停滯狀態(阻塞當前線程),讓出CUP的使用、目的是不讓當前線程獨自霸占該進程所獲的CPU資源,以留一定時間給其他線程執行的機會;

sleep()是Thread類的Static(靜態)的方法;因此他不能改變對象的機鎖,所以當在一個Synchronized塊中調用Sleep()方法是,線程雖然休眠了,但是對象的機鎖并木有被釋放,其他線程無法訪問這個對象(即使睡著也持有對象鎖)。

在sleep()休眠時間期滿后,該線程不一定會立

即執行,這是因為其它線程可能正在運行而且沒有被調度為放棄執行,除非此線程具有更高的優先級。

wait()方法

wait()方法是Object類里的方法;當一個線程執行到wait()方法時,它就進入到一個和該對象相關的等待池中,同時失去(釋放)了對象的機鎖(暫時失去機鎖,wait(long timeout)超時時間到后還需要返還對象鎖);其他線程可以訪問

wait()使用notify或者notifyAlll或者指定睡眠時間來喚醒當前等待池中的線程。

wiat()必須放在synchronized block中,否則會在program runtime時扔出”java.lang.IllegalMonitorStateException“異常。

所以sleep()和wait()方法的最大區別是:

sleep()睡眠時,保持對象鎖,仍然占有該鎖

而wait()睡眠時,釋放對象鎖

但是wait()和sleep()都可以通過interrupt()方法打斷線程的暫停狀態,從而使線程立刻拋出InterruptedException(但不建議使用該方法)。




publicclassThreadTestimplementsRunnable {

intnumber = 10;

publicvoidfirstMethod()throwsException {

synchronized(this) {

number += 100;

System.out.println(number);

}

}

publicvoidsecondMethod()throwsException {

synchronized(this) {

/**

* (休息2S,阻塞線程)

* 以驗證當前線程對象的機鎖被占用時,

* 是否被可以訪問其他同步代碼塊

*/

Thread.sleep(2000);

//this.wait(2000);

number *= 200;

}

}

@Override

publicvoidrun() {

try{

firstMethod();

}catch(Exception e) {

e.printStackTrace();

}

}

publicstaticvoidmain(String[] args)throwsException {

ThreadTest threadTest =newThreadTest();

Thread thread =newThread(threadTest);

thread.start();

threadTest.secondMethod();

}

}

在主線程的普通方法會先被執行,線程的方法也會被執行,他們是交替執行的

main()方法中實例化ThreadTest并啟動該線程,然后調用該線程的一個方法(secondMethod()),因為在主線程中調用方法,所以調用的普通方法secondMethod())會先被執行(但并不是普通方法執行完畢該對象的線程方法才執行,普通方法執行過程中,該線程的方法也會被執行,他們是交替執行的,只是在主線程的普通方法會先被執行而已),所以程序運行時會先執行secondMethod(),而secondMethod()方法代碼片段中有synchronized block,因此secondMethod方法被執行后,該方法會占有該對象機鎖導致該對象的線程方法一直處于阻塞狀態,不能執行,直到secondeMethod釋放鎖

使用Thread.sleep(2000)方法時,因為sleep在阻塞線程的同時,并持有該對象鎖,所以該對象的其他同步線程(secondMethod())無法執行,直到synchronized block執行完畢(sleep休眠完畢),secondMethod()方法才可以執行,因此輸出結果為number*200+100;

使用this.wait(2000)方法時,secondMethod()方法被執行后也鎖定了該對象的機鎖,執行到this.wait(2000)時,該方法會休眠2S并釋當前持有的鎖,此時該線程的同步方法會被執行(因為secondMethod持有的鎖,已經被wait()所釋放),因此輸出的結果為:number+100;

【顯示流程】

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容