您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“Java中線程的狀態(tài)分別有哪幾種”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
1. 初始(NEW):新創(chuàng)建了一個(gè)線程對(duì)象,但還沒有調(diào)用start()方法?! ?/p>
2. 運(yùn)行(RUNNABLE):Java線程中將就緒(ready)和運(yùn)行中(running)兩種狀態(tài)籠統(tǒng)地稱為“運(yùn)行”。 線程對(duì)象創(chuàng)建后,其他線程(比如main線程)調(diào)用了該對(duì)象的start()方法。該狀態(tài)的線程位于可運(yùn)行線程池中,等待被線程調(diào)度選中,獲取CPU的使用權(quán),此時(shí)處于就緒狀態(tài)(ready)。就緒狀態(tài)的線程在獲得CPU時(shí)間片后變?yōu)檫\(yùn)行中狀態(tài)(running)。
3.阻塞(BLOCKED):表示線程阻塞于鎖。
4.等待(WAITING):進(jìn)入該狀態(tài)的線程需要等待其他線程做出一些特定動(dòng)作(通知或中斷)。
5.超時(shí)等待(TIMED_WAITING):該狀態(tài)不同于WAITING,它可以在指定的時(shí)間后自行返回。
6. 終止(TERMINATED):表示該線程已經(jīng)執(zhí)行完畢。
1. 初始狀態(tài)
實(shí)現(xiàn)Runnable接口和繼承Thread可以得到一個(gè)線程類,new一個(gè)實(shí)例出來,線程就進(jìn)入了初始狀態(tài)。
2.1. 就緒狀態(tài)
就緒狀態(tài)只是說你資格運(yùn)行,調(diào)度程序沒有挑選到你,你就永遠(yuǎn)是就緒狀態(tài)。調(diào)用線程的start()方法,此線程進(jìn)入就緒狀態(tài)。當(dāng)前線程sleep()方法結(jié)束,其他線程join()結(jié)束,等待用戶輸入完畢,某個(gè)線程拿到對(duì)象鎖,這些線程也將進(jìn)入就緒狀態(tài)。當(dāng)前線程時(shí)間片用完了,調(diào)用當(dāng)前線程的yield()方法,當(dāng)前線程進(jìn)入就緒狀態(tài)。鎖池里的線程拿到對(duì)象鎖后,進(jìn)入就緒狀態(tài)。
2.2.運(yùn)行中狀態(tài)
線程調(diào)度程序從可運(yùn)行池中選擇一個(gè)線程作為當(dāng)前線程時(shí)線程所處的狀態(tài)。這也是線程進(jìn)入運(yùn)行狀態(tài)的唯一一種方式。
3. 阻塞狀態(tài)
阻塞狀態(tài)是線程阻塞在進(jìn)入synchronized關(guān)鍵字修飾的方法或代碼塊(獲取鎖)時(shí)的狀態(tài)。
4. 等待
處于這種狀態(tài)的線程不會(huì)被分配CPU執(zhí)行時(shí)間,它們要等待被顯式地喚醒,否則會(huì)處于無限期等待的狀態(tài)。
5. 超時(shí)等待
處于這種狀態(tài)的線程不會(huì)被分配CPU執(zhí)行時(shí)間,不過無須無限期等待被其他線程顯示地喚醒,在達(dá)到一定時(shí)間后它們會(huì)自動(dòng)喚醒。
6. 終止?fàn)顟B(tài)
當(dāng)線程的run()方法完成時(shí),或者主線程的main()方法完成時(shí),我們就認(rèn)為它終止了。這個(gè)線程對(duì)象也許是活的,但是,它已經(jīng)不是一個(gè)單獨(dú)執(zhí)行的線程。線程一旦終止了,就不能復(fù)生。 在一個(gè)終止的線程上調(diào)用start()方法,會(huì)拋出java.lang.IllegalThreadStateException異常。
7.等待隊(duì)列
調(diào)用obj的wait(), notify()方法前,必須獲得obj鎖,也就是必須寫在synchronized(obj) 代碼段內(nèi)。 與等待隊(duì)列相關(guān)的步驟和圖
線程1獲取對(duì)象A的鎖,正在使用對(duì)象A。
線程1調(diào)用對(duì)象A的wait()方法。
線程1釋放對(duì)象A的鎖,并馬上進(jìn)入等待隊(duì)列。
鎖池里面的對(duì)象爭(zhēng)搶對(duì)象A的鎖。
線程5獲得對(duì)象A的鎖,進(jìn)入synchronized塊,使用對(duì)象A。
線程5調(diào)用對(duì)象A的notifyAll()方法,喚醒所有線程,所有線程進(jìn)入同步隊(duì)列。若線程5調(diào)用對(duì)象A的notify()方法,則喚醒一個(gè)線程,不知道會(huì)喚醒誰,被喚醒的那個(gè)線程進(jìn)入同步隊(duì)列。
notifyAll()方法所在synchronized結(jié)束,線程5釋放對(duì)象A的鎖。
同步隊(duì)列的線程爭(zhēng)搶對(duì)象鎖,但線程1什么時(shí)候能搶到就不知道了。
同步隊(duì)列狀態(tài)
當(dāng)前線程想調(diào)用對(duì)象A的同步方法時(shí),發(fā)現(xiàn)對(duì)象A的鎖被別的線程占有,此時(shí)當(dāng)前線程進(jìn)入同步隊(duì)列。簡(jiǎn)言之,同步隊(duì)列里面放的都是想爭(zhēng)奪對(duì)象鎖的線程。
當(dāng)一個(gè)線程1被另外一個(gè)線程2喚醒時(shí),1線程進(jìn)入同步隊(duì)列,去爭(zhēng)奪對(duì)象鎖。同步隊(duì)列是在同步的環(huán)境下才有的概念,一個(gè)對(duì)象對(duì)應(yīng)一個(gè)同步隊(duì)列。
幾個(gè)方法的比較
Thread.sleep(long millis),一定是當(dāng)前線程調(diào)用此方法,當(dāng)前線程進(jìn)入TIMED_WAITING狀態(tài),但不釋放對(duì)象鎖,millis后線程自動(dòng)蘇醒進(jìn)入就緒狀態(tài)。作用:給其它線程執(zhí)行機(jī)會(huì)的最佳方式。
Thread.yield(),一定是當(dāng)前線程調(diào)用此方法,當(dāng)前線程放棄獲取的CPU時(shí)間片,但不釋放鎖資源,由運(yùn)行狀態(tài)變?yōu)榫途w狀態(tài),讓OS再次選擇線程。作用:讓相同優(yōu)先級(jí)的線程輪流執(zhí)行,但并不保證一定會(huì)輪流執(zhí)行。實(shí)際中無法保證yield()達(dá)到讓步目的,因?yàn)樽尣降木€程還有可能被線程調(diào)度程序再次選中。Thread.yield()不會(huì)導(dǎo)致阻塞。該方法與sleep()類似,只是不能由用戶指定暫停多長(zhǎng)時(shí)間。
t.join()/t.join(long millis),當(dāng)前線程里調(diào)用其它線程t的join方法,當(dāng)前線程進(jìn)入WAITING/TIMED_WAITING狀態(tài),當(dāng)前線程不會(huì)釋放已經(jīng)持有的對(duì)象鎖。線程t執(zhí)行完畢或者millis時(shí)間到,當(dāng)前線程進(jìn)入就緒狀態(tài)。
obj.wait(),當(dāng)前線程調(diào)用對(duì)象的wait()方法,當(dāng)前線程釋放對(duì)象鎖,進(jìn)入等待隊(duì)列。依靠notify()/notifyAll()喚醒或者wait(long timeout) timeout時(shí)間到自動(dòng)喚醒。
obj.notify()喚醒在此對(duì)象監(jiān)視器上等待的單個(gè)線程,選擇是任意性的。notifyAll()喚醒在此對(duì)象監(jiān)視器上等待的所有線程。
“Java中線程的狀態(tài)分別有哪幾種”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。