日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Java Thread(線程)案例詳解sleep和wait的區(qū)別

 9loong 2012-10-10
   上次對(duì)Java Thread有了總體的概述與總結(jié),當(dāng)然大多都是理論上的,這次我將詳解Thread中兩個(gè)常用且容易疑惑的方法、并通過實(shí)例代碼進(jìn)行解疑。。。

F區(qū)別


sleep()方法
  sleep()使當(dāng)前線程進(jìn)入停滯狀態(tài)(阻塞當(dāng)前線程),讓出CUP的使用、目的是不讓當(dāng)前線程獨(dú)自霸占該進(jìn)程所獲的CPU資源,以留一定時(shí)間給其他線程執(zhí)行的機(jī)會(huì);
   sleep()是Thread類的Static(靜態(tài))的方法;因此他不能改變對(duì)象的機(jī)鎖,所以當(dāng)在一個(gè)Synchronized塊中調(diào)用Sleep()方法是,線程雖然休眠了,但是對(duì)象的機(jī)鎖并木有被釋放,其他線程無法訪問這個(gè)對(duì)象(即使睡著也持有對(duì)象鎖)。
  在sleep()休眠時(shí)間期滿后,該線程不一定會(huì)立即執(zhí)行,這是因?yàn)槠渌€程可能正在運(yùn)行而且沒有被調(diào)度為放棄執(zhí)行,除非此線程具有更高的優(yōu)先級(jí)。 
   
wait()方法
  wait()方法是Object類里的方法;當(dāng)一個(gè)線程執(zhí)行到wait()方法時(shí),它就進(jìn)入到一個(gè)和該對(duì)象相關(guān)的等待池中,同時(shí)失去(釋放)了對(duì)象的機(jī)鎖(暫時(shí)失去機(jī)鎖,wait(long timeout)超時(shí)時(shí)間到后還需要返還對(duì)象鎖);其他線程可以訪問;
  wait()使用notify或者notifyAlll或者指定睡眠時(shí)間來喚醒當(dāng)前等待池中的線程。
  wiat()必須放在synchronized block中,否則會(huì)在program runtime時(shí)扔出”java.lang.IllegalMonitorStateException“異常。


 
  所以sleep()和wait()方法的最大區(qū)別是:
    sleep()睡眠時(shí),保持對(duì)象鎖,仍然占有該鎖;
    而wait()睡眠時(shí),釋放對(duì)象鎖。
  但是wait()和sleep()都可以通過interrupt()方法打斷線程的暫停狀態(tài),從而使線程立刻拋出InterruptedException(但不建議使用該方法)。

F代碼

View Code
/**
* Thread sleep和wait區(qū)別
*
@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,阻塞線程)
* 以驗(yàn)證當(dāng)前線程對(duì)象的機(jī)鎖被占用時(shí),
* 是否被可以訪問其他同步代碼塊
*/
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()方法輸出結(jié)果:【顯示輸出】
使用Wait()方法輸出結(jié)果:【顯示輸出】

我 們來大致分析一下此段代碼,main()方法中實(shí)例化ThreadTest并啟動(dòng)該線程,然后調(diào)用該線程的一個(gè)方法(secondMethod()),因 為在主線程中調(diào)用方法,所以調(diào)用的普通方法secondMethod())會(huì)先被執(zhí)行(但并不是普通方法執(zhí)行完畢該對(duì)象的線程方法才執(zhí)行,普通方法執(zhí)行過 程中,該線程的方法也會(huì)被執(zhí)行,他們是交替執(zhí)行的,只是在主線程的普通方法會(huì)先被執(zhí)行而已),所以程序運(yùn)行時(shí)會(huì)先執(zhí)行secondMethod(),而 secondMethod()方法代碼片段中有synchronized block,因此secondMethod方法被執(zhí)行后,該方法會(huì)占有該對(duì)象機(jī)鎖導(dǎo)致該對(duì)象的線程方法一直處于阻塞狀態(tài),不能執(zhí)行,直到 secondeMethod釋放鎖;
使用Thread.sleep(2000)方法時(shí),因?yàn)閟leep在阻塞線程的同時(shí),并持有該對(duì)象鎖,所以該 對(duì)象的其他同步線程(secondMethod())無法執(zhí)行,直到synchronized block執(zhí)行完畢(sleep休眠完畢),secondMethod()方法才可以執(zhí)行,因此輸出結(jié)果為number*200+100;
使用 this.wait(2000)方法時(shí),secondMethod()方法被執(zhí)行后也鎖定了該對(duì)象的機(jī)鎖,執(zhí)行到this.wait(2000)時(shí),該方 法會(huì)休眠2S并釋當(dāng)前持有的鎖,此時(shí)該線程的同步方法會(huì)被執(zhí)行(因?yàn)閟econdMethod持有的鎖,已經(jīng)被wait()所釋放),因此輸出的結(jié)果 為:number+100;
【顯示流程】 
sleep()和wait()方法的區(qū)別已經(jīng)講解完畢,若對(duì)線程有興趣的童鞋我在諾諾的問問:在main方法中最后行加入“System.out.println("number="+threadTest.number);”猜猜會(huì)輸出什么結(jié)果。。。


(###)

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多