更新時間:2022-06-15 來源:黑馬程序員 瀏覽量:
Java是支持多線程的語言之一,它對多線程編程提供了內置的支持,可以使程序同時執(zhí)行多個執(zhí)行片段。線程的6種狀態(tài)和轉換如下圖:
*新建
當一個線程對象被創(chuàng)建,但還未調用 start 方法時處于新建狀態(tài)
此時未與操作系統(tǒng)底層線程關聯
*可運行
調用了 start 方法,就會由新建進入可運行
此時與底層線程關聯,由操作系統(tǒng)調度執(zhí)行
*終結
線程內代碼已經執(zhí)行完畢,由可運行進入終結,此時會取消與底層線程關聯
*阻塞
當獲取鎖失敗后,由可運行進入 Monitor 的阻塞隊列阻塞,此時不占用 cpu 時間
當持鎖線程釋放鎖時,會按照一定規(guī)則喚醒阻塞隊列中的阻塞線程,喚醒后的線程進入可運行狀態(tài)
*等待
當獲取鎖成功后,但由于條件不滿足,調用了 wait() 方法,此時從可運行狀態(tài)釋放鎖進入 Monitor 等待集合等待,同樣不占用 cpu 時間
當其它持鎖線程調用 notify() 或 notifyAll() 方法,會按照一定規(guī)則喚醒等待集合中的等待線程,恢復為**可運行狀態(tài)
*有時限等待
當獲取鎖成功后,但由于條件不滿足,調用了 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 等方法也可以讓線程等待和喚醒。
*五種狀態(tài)
五種狀態(tài)的說法來自于操作系統(tǒng)層面的劃分
運行態(tài):分到 cpu 時間,能真正執(zhí)行線程內代碼的
就緒態(tài):有資格分到 cpu 時間,但還未輪到它的
阻塞態(tài):沒資格分到 cpu 時間的,涵蓋了 java 狀態(tài)中提到的阻塞、等待、有時限等待.多出了阻塞 I/O,指線程在調用阻塞 I/O 時,實際活由 I/O 設備完成,此時線程無事可做,只能干等
新建與終結態(tài):與 java 中同名狀態(tài)類似,不再啰嗦