sleep()方法
sleep()使當前線程進入停滯狀態(阻塞當前線程),讓出CUP的使用、目的是不讓當前線程獨自霸佔該進程所獲的CPU資源,以留一定時間給其他線程執行的機會;
sleep()是Thread類的Static(靜態)的方法;因此他不能改變對象的機鎖,所以當在一個Synchronized塊中調用Sleep()方法是,線程雖然休眠了,但是對象的機鎖並木有被釋放,其他線程無法訪問這個對象(即使睡着也持有對象鎖)。
在sleep()休眠時間期滿後,該線程不一定會立即執行,這是因爲其它線程可能正在運行而且沒有被調度爲放棄執行,除非此線程具有更高的優先級。
sleep()是Thread類的Static(靜態)的方法;因此他不能改變對象的機鎖,所以當在一個Synchronized塊中調用Sleep()方法是,線程雖然休眠了,但是對象的機鎖並木有被釋放,其他線程無法訪問這個對象(即使睡着也持有對象鎖)。
在sleep()休眠時間期滿後,該線程不一定會立即執行,這是因爲其它線程可能正在運行而且沒有被調度爲放棄執行,除非此線程具有更高的優先級。
wait()方法
wait()方法是Object類裏的方法;當一個線程執行到wait()方法時,它就進入到一個和該對象相關的等待池中,同時失去(釋放)了對象的機鎖(暫時失去機鎖,wait(long timeout)超時時間到後還需要返還對象鎖);其他線程可以訪問;
wait()使用notify或者notifyAlll或者指定睡眠時間來喚醒當前等待池中的線程。
wiat()必須放在synchronized block中,否則會在program runtime時扔出”java.lang.IllegalMonitorStateException“異常。
wait()使用notify或者notifyAlll或者指定睡眠時間來喚醒當前等待池中的線程。
wiat()必須放在synchronized block中,否則會在program runtime時扔出”java.lang.IllegalMonitorStateException“異常。
所以sleep()和wait()方法的最大區別是:
sleep()睡眠時,保持對象鎖,仍然佔有該鎖;
而wait()睡眠時,釋放對象鎖。
但是wait()和sleep()都可以通過interrupt()方法打斷線程的暫停狀態,從而使線程立刻拋出InterruptedException(但不建議使用該方法)。
sleep()睡眠時,保持對象鎖,仍然佔有該鎖;
而wait()睡眠時,釋放對象鎖。
但是wait()和sleep()都可以通過interrupt()方法打斷線程的暫停狀態,從而使線程立刻拋出InterruptedException(但不建議使用該方法)。
/**
* 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,阻塞線程)
* 以驗證當前線程對象的機鎖被佔用時,
* 是否被可以訪問其他同步代碼塊
*/
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()方法輸出結果:【顯示輸出】
我們來大致分析一下此段代碼,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;
【顯示流程】
sleep()和wait()方法的區別已經講解完畢,若對線程有興趣的童鞋我在諾諾的問問:在main方法中最後行加入“System.out.println("number="+threadTest.number);”猜猜會輸出什麼結果。。。J
我們來大致分析一下此段代碼,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;
【顯示流程】
sleep()和wait()方法的區別已經講解完畢,若對線程有興趣的童鞋我在諾諾的問問:在main方法中最後行加入“System.out.println("number="+threadTest.number);”猜猜會輸出什麼結果。。。J