上次對Java Thread有了總體的概述與總結,當然大多都是理論上的,這次我將詳解Thread中兩個(gè)常用且容易疑惑的方法、并通過(guò)實(shí)例代碼進(jìn)行解疑。。。
sleep()方法
sleep()使當前線(xiàn)程進(jìn)入停滯狀態(tài)(阻塞當前線(xiàn)程),讓出CUP的使用、目的是不讓當前線(xiàn)程獨自霸占該進(jìn)程所獲的CPU資源,以留一定時(shí)間給其他線(xiàn)程執行的機會(huì );
sleep()是Thread類(lèi)的Static(靜態(tài))的方法;因此他不能改變對象的機鎖,所以當在一個(gè)Synchronized塊中調用Sleep()方法是,線(xiàn)程雖然休眠了,但是對象的機鎖并木有被釋放,其他線(xiàn)程無(wú)法訪(fǎng)問(wèn)這個(gè)對象(即使睡著(zhù)也持有對象鎖)。
在sleep()休眠時(shí)間期滿(mǎn)后,該線(xiàn)程不一定會(huì )立即執行,這是因為其它線(xiàn)程可能正在運行而且沒(méi)有被調度為放棄執行,除非此線(xiàn)程具有更高的優(yōu)先級。
wait()方法
wait()方法是Object類(lèi)里的方法;當一個(gè)線(xiàn)程執行到wait()方法時(shí),它就進(jìn)入到一個(gè)和該對象相關(guān)的等待池中,同時(shí)失去(釋放)了對象的機鎖(暫時(shí)失去機鎖,wait(long timeout)超時(shí)時(shí)間到后還需要返還對象鎖);其他線(xiàn)程可以訪(fǎng)問(wèn);
wait()使用notify或者notifyAlll或者指定睡眠時(shí)間來(lái)喚醒當前等待池中的線(xiàn)程。
wiat()必須放在synchronized block中,否則會(huì )在program runtime時(shí)扔出”java.lang.IllegalMonitorStateException“異常。
所以sleep()和wait()方法的最大區別是:
sleep()睡眠時(shí),保持對象鎖,仍然占有該鎖;
而wait()睡眠時(shí),釋放對象鎖。
但是wait()和sleep()都可以通過(guò)interrupt()方法打斷線(xiàn)程的暫停狀態(tài),從而使線(xiàn)程立刻拋出InterruptedException(但不建議使用該方法)。
View Code /**
* Thread sleep和wait區別
* @author DreamSea
* 2012-1-15
*/
public class ThreadTest implements Runnable {
int number = 10;
public void firstMethod() throws Exception {
synchronized (this) {
number += 100;
System.out.println(number);
}
}
public void secondMethod() throws Exception {
synchronized (this) {
/**
* (休息2S,阻塞線(xiàn)程)
* 以驗證當前線(xiàn)程對象的機鎖被占用時(shí),
* 是否被可以訪(fǎng)問(wèn)其他同步代碼塊
*/
Thread.sleep(2000);
//this.wait(2000);
number *= 200;
}
}
@Override
public void run() {
try {
firstMethod();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
ThreadTest threadTest = new ThreadTest();
Thread thread = new Thread(threadTest);
thread.start();
threadTest.secondMethod();
}
}
使用Sleep()方法輸出結果:【顯示輸出】
使用Wait()方法輸出結果:【顯示輸出】
我們來(lái)大致分析一下此段代碼,main()方法中實(shí)例化ThreadTest并啟動(dòng)該線(xiàn)程,然后調用該線(xiàn)程的一個(gè)方法(secondMethod()),因為在主線(xiàn)程中調用方法,所以調用的普通方法secondMethod())會(huì )先被執行(但并不是普通方法執行完畢該對象的線(xiàn)程方法才執行,普通方法執行過(guò)程中,該線(xiàn)程的方法也會(huì )被執行,他們是交替執行的,只是在主線(xiàn)程的普通方法會(huì )先被執行而已),所以程序運行時(shí)會(huì )先執行secondMethod(),而secondMethod()方法代碼片段中有synchronized block,因此secondMethod方法被執行后,該方法會(huì )占有該對象機鎖導致該對象的線(xiàn)程方法一直處于阻塞狀態(tài),不能執行,直到secondeMethod釋放鎖;
使用Thread.sleep(2000)方法時(shí),因為sleep在阻塞線(xiàn)程的同時(shí),并持有該對象鎖,所以該對象的其他同步線(xiàn)程(secondMethod())無(wú)法執行,直到synchronized block執行完畢(sleep休眠完畢),secondMethod()方法才可以執行,因此輸出結果為number*200+100;
使用this.wait(2000)方法時(shí),secondMethod()方法被執行后也鎖定了該對象的機鎖,執行到this.wait(2000)時(shí),該方法會(huì )休眠2S并釋當前持有的鎖,此時(shí)該線(xiàn)程的同步方法會(huì )被執行(因為secondMethod持有的鎖,已經(jīng)被wait()所釋放),因此輸出的結果為:number+100;
【顯示流程】
sleep()和wait()方法的區別已經(jīng)講解完畢,若對線(xiàn)程有興趣的童鞋我在諾諾的問(wèn)問(wèn):在main方法中最后行加入“System.out.println("number="+threadTest.number);”猜猜會(huì )輸出什么結果。。。
(###)
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請
點(diǎn)擊舉報。