新聞中心
1. 線程狀態(tài)-六種狀態(tài)
線程的狀態(tài)可以參考JDK中的Thread類中的枚舉State,存在六種狀態(tài)

創(chuàng)新互聯建站長期為數千家客戶提供的網站建設服務,團隊從業(yè)經驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯網生態(tài)環(huán)境。為伊美企業(yè)提供專業(yè)的網站設計、成都網站建設,伊美網站改版等技術服務。擁有十多年豐富建站經驗和眾多成功案例,為您定制開發(fā)。
public enum State {
//尚未啟動的線程的線程狀態(tài)
NEW,
//可運行線程的線程狀態(tài)
RUNNABLE,
//線程阻塞等待監(jiān)視器鎖的線程狀態(tài)
BLOCKED,
//等待線程的線程狀態(tài)
WAITING,
//具有指定等待時間的等待線程的線程狀態(tài)(有限等待)
TIMED_WAITING,
//已終止線程的線程狀態(tài)。線程已完成執(zhí)行
TERMINATED;
}
六種狀態(tài)介紹:
新建(NEW)
- 當一個線程對象被創(chuàng)建,但還未調用 start 方法時處于新建狀態(tài)
- 此時未與操作系統底層線程關聯
可運行(RUNNABLE):
- 調用了 start 方法,就會由新建進入可運行
- 此時與底層線程關聯,由操作系統調度執(zhí)行
終結(TERMINATED)
- 線程內代碼已經執(zhí)行完畢,由可運行進入終結
- 此時會取消與底層線程關聯
阻塞(BLOCKED)
- 當獲取鎖失敗后,由可運行進入 Monitor 的阻塞隊列阻塞,此時不占用 cpu 時間
- 當持鎖線程釋放鎖時,會按照一定規(guī)則喚醒阻塞隊列中的阻塞線程,喚醒后的線程進入可運行狀態(tài)
等待(WAITING)
- 當獲取鎖成功后,但由于條件不滿足,調用了 wait() 方法,此時從可運行狀態(tài)釋放鎖進入 Monitor 等待集合等待,同樣不占用 cpu 時間
- 當其它持鎖線程調用 notify() 或 notifyAll() 方法,會按照一定規(guī)則喚醒等待集合中的等待線程,恢復為可運行狀態(tài)
有時限等待(TIMED_WAITING)
- 當獲取鎖成功后,但由于條件不滿足,調用了 wait(long) 方法,此時從可運行狀態(tài)釋放鎖進入 Monitor 等待集合進行有時限等待,同樣不占用 cpu 時間
- 當其它持鎖線程調用 notify() 或 notifyAll() 方法,會按照一定規(guī)則喚醒等待集合中的有時限等待線程,恢復為可運行狀態(tài),并重新去競爭鎖
- 如果等待超時,也會從有時限等待狀態(tài)恢復為可運行狀態(tài),并重新去競爭鎖
- 還有一種情況是調用 sleep(long) 方法也會從可運行狀態(tài)進入有時限等待狀態(tài),但與 Monitor 無關,不需要主動喚醒,超時時間到自然恢復為可運行狀態(tài)
其它情況(只需了解)
- 可以用 interrupt() 方法打斷等待、有時限等待的線程,讓它們恢復為可運行狀態(tài)
- park,unpark 等方法也可以讓線程等待和喚醒
2. 線程狀態(tài)-五種狀態(tài)
五種狀態(tài)的說法來自于操作系統層面的劃分
- 運行態(tài):分到 cpu 時間,能真正執(zhí)行線程內代碼的
- 就緒態(tài):有資格分到 cpu 時間,但還未輪到它的
- 阻塞態(tài):沒資格分到 cpu 時間的
- 涵蓋了 java 狀態(tài)中提到的阻塞、等待、有時限等待
- 多出了阻塞 I/O,指線程在調用阻塞 I/O 時,實際活由 I/O 設備完成,此時線程無事可做,只能干等
- 新建與終結態(tài):與 java 中同名狀態(tài)類似,不再啰嗦
3. wait和sleep方法的不同?
共同點
wait() ,wait(long) 和 sleep(long) 的效果都是讓當前線程暫時放棄 CPU 的使用權,進入阻塞狀態(tài)
不同點
1.方法歸屬不同
- sleep(long) 是 Thread 的靜態(tài)方法
- 而 wait(),wait(long) 都是 Object 的成員方法,每個對象都有 醒來時機不同
- 執(zhí)行 sleep(long) 和 wait(long) 的線程都會在等待相應毫秒后醒來
- wait(long) 和 wait() 還可以被 notify 喚醒,wait() 如果不喚醒就一直等下去
- 它們都可以被打斷喚醒
2.鎖特性不同(重點)
- wait 方法的調用必須先獲取 wait 對象的鎖,而 sleep 則無此限制
- wait 方法執(zhí)行后會釋放對象鎖,允許其它線程獲得該對象鎖(我放棄 cpu,但你們還可以用)
- 而 sleep 如果在 synchronized 代碼塊中執(zhí)行,并不會釋放對象鎖(我放棄 cpu,你們也用不了)
3. 線程狀態(tài)面試題
面試官:線程包括哪些狀態(tài),狀態(tài)之間是如何變化的?
候選人:
在JDK中的Thread類中的枚舉State里面定義了6中線程的狀態(tài)分別是:新建、可運行、終結、阻塞、等待和有時限等待六種。
關于線程的狀態(tài)切換情況比較多。我分別介紹一下:
當一個線程對象被創(chuàng)建,但還未調用 start 方法時處于新建狀態(tài),調用了 start 方法,就會由新建進入可運行狀態(tài)。如果線程內代碼已經執(zhí)行完畢,由可運行進入終結狀態(tài)。當然這些是一個線程正常執(zhí)行情況。
如果線程獲取鎖失敗后,由可運行進入 Monitor 的阻塞隊列阻塞,只有當持鎖線程釋放鎖時,會按照一定規(guī)則喚醒阻塞隊列中的阻塞線程,喚醒后的線程進入可運行狀態(tài)。
如果線程獲取鎖成功后,但由于條件不滿足,調用了 wait() 方法,此時從可運行狀態(tài)釋放鎖等待狀態(tài),當其它持鎖線程調用 notify() 或 notifyAll() 方法,會恢復為可運行狀態(tài)。
還有一種情況是調用 sleep(long) 方法也會從可運行狀態(tài)進入有時限等待狀態(tài),不需要主動喚醒,超時時間到自然恢復為可運行狀態(tài)。
當前名稱:線程包括哪些狀態(tài),狀態(tài)之間是如何變化?
分享URL:http://m.5511xx.com/article/cdssdpp.html


咨詢
建站咨詢
