sleep()方法
sleep()使當(dāng)前線程進(jìn)入停滯狀態(tài)(阻塞當(dāng)前線程),讓出CUP的使用、目的是不讓當(dāng)前線程獨自霸占該進(jìn)程所獲的CPU資源,以留一定時間給其他線程執(zhí)行的機(jī)會;
sleep()是Thread類的Static(靜態(tài))的方法;因此他不能改變對象的機(jī)鎖,所以當(dāng)在一個Synchronized塊中調(diào)用Sleep()方法是,線程雖然休眠了,但是對象的機(jī)鎖并木有被釋放,其他線程無法訪問這個對象(即使睡著也持有對象鎖)。
在sleep()休眠時間期滿后,該線程不一定會立
即執(zhí)行,這是因為其它線程可能正在運行而且沒有被調(diào)度為放棄執(zhí)行,除非此線程具有更高的優(yōu)先級。
wait()方法
wait()方法是Object類里的方法;當(dāng)一個線程執(zhí)行到wait()方法時,它就進(jìn)入到一個和該對象相關(guān)的等待池中,同時失去(釋放)了對象的機(jī)鎖(暫時失去機(jī)鎖,wait(long timeout)超時時間到后還需要返還對象鎖);其他線程可以訪問;
wait()使用notify或者notifyAlll或者指定睡眠時間來喚醒當(dāng)前等待池中的線程。
wiat()必須放在synchronized block中,否則會在program runtime時扔出”java.lang.IllegalMonitorStateException“異常。
所以sleep()和wait()方法的最大區(qū)別是:
sleep()睡眠時,保持對象鎖,仍然占有該鎖;
而wait()睡眠時,釋放對象鎖。
但是wait()和sleep()都可以通過interrupt()方法打斷線程的暫停狀態(tài),從而使線程立刻拋出InterruptedException(但不建議使用該方法)。
publicclassThreadTestimplementsRunnable {
intnumber = 10;
publicvoidfirstMethod()throwsException {
synchronized(this) {
number += 100;
System.out.println(number);
}
}
publicvoidsecondMethod()throwsException {
synchronized(this) {
/**
* (休息2S,阻塞線程)
* 以驗證當(dāng)前線程對象的機(jī)鎖被占用時,
* 是否被可以訪問其他同步代碼塊
*/
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();
}
}
在主線程的普通方法會先被執(zhí)行,線程的方法也會被執(zhí)行,他們是交替執(zhí)行的
main()方法中實例化ThreadTest并啟動該線程,然后調(diào)用該線程的一個方法(secondMethod()),因為在主線程中調(diào)用方法,所以調(diào)用的普通方法secondMethod())會先被執(zhí)行(但并不是普通方法執(zhí)行完畢該對象的線程方法才執(zhí)行,普通方法執(zhí)行過程中,該線程的方法也會被執(zhí)行,他們是交替執(zhí)行的,只是在主線程的普通方法會先被執(zhí)行而已),所以程序運行時會先執(zhí)行secondMethod(),而secondMethod()方法代碼片段中有synchronized block,因此secondMethod方法被執(zhí)行后,該方法會占有該對象機(jī)鎖導(dǎo)致該對象的線程方法一直處于阻塞狀態(tài),不能執(zhí)行,直到secondeMethod釋放鎖;
使用Thread.sleep(2000)方法時,因為sleep在阻塞線程的同時,并持有該對象鎖,所以該對象的其他同步線程(secondMethod())無法執(zhí)行,直到synchronized block執(zhí)行完畢(sleep休眠完畢),secondMethod()方法才可以執(zhí)行,因此輸出結(jié)果為number*200+100;
使用this.wait(2000)方法時,secondMethod()方法被執(zhí)行后也鎖定了該對象的機(jī)鎖,執(zhí)行到this.wait(2000)時,該方法會休眠2S并釋當(dāng)前持有的鎖,此時該線程的同步方法會被執(zhí)行(因為secondMethod持有的鎖,已經(jīng)被wait()所釋放),因此輸出的結(jié)果為:number+100;
