线程打印状态_Java线程状态的转换
根據(jù)上面關(guān)于線程狀態(tài)的介紹我們可以得到下面的線程狀態(tài)轉(zhuǎn)換圖:
BLOCKED與RUNNABLE狀態(tài)的轉(zhuǎn)換
我們?cè)谏厦嬲f到:處于BLOCKED狀態(tài)的線程是因?yàn)樵诘却i的釋放。假如這里有兩個(gè)線程a和b, a線程提前獲得了鎖并且暫未釋放鎖,此時(shí)b就處于BLOCKED狀態(tài)。我們先來看一個(gè)例子:
初看之下,大家可能會(huì)覺得線程a會(huì)先調(diào)用同步方法,同步方法內(nèi)又調(diào)用了Thread.sleep()方法,必然會(huì)輸出TIMED. WAITING, 而線程b因?yàn)榈却€程a釋放鎖所以必然會(huì)輸出BLOCKED。
其實(shí)不然,有兩點(diǎn)需要值得大家注意,-是在測(cè)試方法blockedTest()內(nèi)還有一個(gè)main線程,二是啟動(dòng)線程后執(zhí)行run方法還是需要消耗-定時(shí)間的。 不打斷點(diǎn)的情況下,上面代碼中都應(yīng)該輸出RUNNABLE。
測(cè)試方法的main線程只保證了a,b兩個(gè)線程調(diào)用star()方法(轉(zhuǎn)化為RUNNABLE狀態(tài)), 還沒等兩個(gè)線程真正開始爭(zhēng)奪鎖,就已經(jīng)打印此時(shí)兩個(gè)線程的狀態(tài)(RUNNABLE) 了。
這時(shí)你可能又會(huì)問了,要是我想要打印出BLOCKED狀態(tài)我該怎么處理呢?其實(shí)就處理下測(cè)試方法里的main線程就可以了,你讓它休息一會(huì)兒,打斷點(diǎn)或者調(diào)用Thread .sleep方法就行。
這里需要注意的是main線程休息的時(shí)間,要保證在線程爭(zhēng)奪鎖的時(shí)間內(nèi),不要等到前一個(gè)線程鎖都釋放了你再去爭(zhēng)奪鎖,此時(shí)還是得不到BL OCKED狀態(tài)的。我們把上面的測(cè)試方法blockedTest()改動(dòng)一下:
在這個(gè)例子中,由于main線程休眠,所以線程a的run()方 法跟著執(zhí)行,線程b再接著執(zhí)行。
在線程a執(zhí)行run()調(diào)用testMethod()之后,線程a休眠了2000ms (注意這里是沒有釋放鎖的),main線程休眠完畢,接著b線程執(zhí)行的時(shí)候是爭(zhēng)奪不到鎖的,所以這里輸出:
WAITING狀態(tài)與RUNNABLE狀態(tài)的轉(zhuǎn)換
根據(jù)轉(zhuǎn)換圖我們知道有3個(gè)方法可以使線程從RUNNABL E狀態(tài)轉(zhuǎn)為WAITING狀態(tài)。我們主要介紹”FObject.wait)和Threadjoin()。Object.wait()調(diào)用wait()方法前線程必須持有對(duì)象的鎖。
線程調(diào)用wait)方法時(shí),會(huì)釋放當(dāng)前的鎖,直到有其他線程調(diào)用notlf)ntifyA()方法喚醒等待鎖的線程。
需要注意的是,其他線程調(diào)用notify()方法只會(huì)喚醒單個(gè)等待鎖的線程,如果有多個(gè)線程都在等待這個(gè)鎖的話不一定會(huì)喚醒到之前調(diào)用wait()方法的線程。同樣,調(diào)用notifyAI()方法喚醒所有等待鎖的線程之后,也不一定會(huì)馬上把時(shí)間片分給剛才放棄鎖的那個(gè)線程,具體要看系統(tǒng)的調(diào)度。
Threadjoin()
調(diào)用join()方法不會(huì)釋放鎖,會(huì)一直等待當(dāng)前線程執(zhí)行完畢(轉(zhuǎn)換為TERMINATED狀態(tài))。
我們?cè)侔焉厦娴睦泳€程啟動(dòng)那里改變一下:
要是沒有調(diào)用join方法,main線程不管a線程是否執(zhí)行完畢都會(huì)繼續(xù)往下走。
a線程啟動(dòng)之后馬.上調(diào)用了join方法,這里main線程 就會(huì)等到a線程執(zhí)行完畢,所以這里a線程打印的狀態(tài)固定是TERMIATED。
至于b線程的狀態(tài),有可能打印RUNNABLE (尚未進(jìn)入同步方法),也有可能打印TIMED_ WAITING (進(jìn)入了同步方法)。
TIMED_ WAITING 與RUNNABLE狀態(tài)轉(zhuǎn)換
TIMED_ WAITING與WAITING狀態(tài)類似,只是TIMED_ WAITING狀態(tài)等 待的時(shí)間是指定的。
Thread.sleep(long)
使當(dāng)前線程睡眠指定時(shí)間。需要注意這里的“睡眠”只是暫時(shí)使線程停止執(zhí)行,并不會(huì)釋放鎖。時(shí)間到后,線程會(huì)重新進(jìn)入RUNNABLE狀態(tài)。
Object. wait(ong)
wait(long)方法使線程進(jìn)入TIMED_ WAITING狀態(tài)。這里的waitlong)方法與無(wú)參方法wait)相同的地方是,都可以通過其他線程調(diào)用notfy()或otlyAl()方法來喚醒。
不同的地方是,有參方法wait(long)就算其他線程不來喚醒它,經(jīng)過指定時(shí)間long之后它會(huì)自動(dòng)喚醒,擁有去爭(zhēng)奪鎖的資格。
Thread,join(long)
join(ong)使當(dāng)前線程執(zhí)行指定時(shí)間,并且使線程進(jìn)入TIMED_ WAITING狀態(tài)。
我們?cè)賮砀囊桓膭偛诺氖纠?
這里調(diào)用a. join(1000L),因?yàn)槭侵付司唧wa線程執(zhí)行的時(shí)間的,并且執(zhí)行時(shí)間是小于a線程sleep的時(shí)間,所以a線程狀態(tài)輸出TIMED. _WAITING。b線程狀態(tài)仍然不固定(RUNNABL E或BL OCKED).
線程中斷
在某些情況下,我們?cè)诰€程啟動(dòng)后發(fā)現(xiàn)并不需要它繼續(xù)執(zhí)行下去時(shí),需要中斷線程。目前在Java里還沒有安全直接的方法來停止線程,但是Java提供了線程中斷機(jī)制來處理需要中斷線程的情況。
線程中斷機(jī)制是-種協(xié)作機(jī)制。需要注意,通過中斷操作并不能直接終止一個(gè)線程,而是通知需要被中斷的線程自行處理。
簡(jiǎn)單介紹下Thread類里提供的關(guān)于線程中斷的幾個(gè)方法:
Threadinterrupt(): 中斷線程。這里的中斷線程并不會(huì)立即停止線程,而是設(shè)置線程的中斷狀態(tài)為rue (默認(rèn)是fase) ;
Thread interrupted(): 測(cè)試當(dāng)前線程是否被中斷。線程的中斷狀態(tài)受這個(gè)方法的影響,意思是調(diào)用一次使線程中斷狀態(tài)設(shè)置為true,連續(xù)調(diào)用兩次會(huì)使得這個(gè)線程的中斷狀態(tài)重新轉(zhuǎn)為false;
Thread,isinterrupted(): 測(cè)試當(dāng)前線程是否被中斷。與上面方法不同的是調(diào)用這個(gè)方法并不會(huì)影響線程的中斷狀態(tài)。
在線程中斷機(jī)制里,當(dāng)其他線程通知需要被中斷的線程后,線程中斷的狀態(tài)被設(shè)置為true,但是具體被要求中斷的線程要怎么處理,完全由被中斷線程自己而定,可以在合適的實(shí)際處理中斷請(qǐng)求,也可以完全不處理繼續(xù)執(zhí)行下去。
總結(jié)
以上是生活随笔為你收集整理的线程打印状态_Java线程状态的转换的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle建表代码,Oracle 建表
- 下一篇: java美元兑换,(Java实现) 美元