線程有自己的狀態,看下圖:
上圖基本描述的線程的生命狀態,有的地方也會將凍結狀態分為兩種,但這沒多大意義,明白就好,上圖的流程也有少畫的,詳細會解釋。解釋一下各種狀態
消亡狀態:不用說,線程死了。
創建狀態:new Thread()就代表創建了一個線程
運行狀態:thread.start()之后就開始運行現場,不過有可用沒有搶到CPU執行權,所以有可能在阻塞狀態等待。
凍結狀態:sleep或者wait會引起凍結狀態,何為凍結狀態,就是線程主動放棄了執行資格(sleep和wait的區別下面會做解釋)。
阻塞狀態:線程有執行資格,但沒有執行權,何為執行權?就是CPU沒輪到它呢。
sleep與wait的區別:
sleep(毫秒數) : 使用這種方式放棄的執行資格,不會放棄它持有的鎖。
wait:使用這種方式放棄的執行資格,會放棄它持有的鎖,并且進到鎖池,等待其他持有此對象的線程調用了notify或者notifyAll方法它才能重新拿到鎖并且回到阻塞狀態等待執行。
notify或者notifyAll:
notify:只會喚醒一個線程,并且是誰先wait的先喚醒誰。
notifyAll:會喚醒此對象鎖的鎖池中所有的線程。
wait和notify,notifyAll方法容易產生的錯誤:
這三個方法的調用必須是在有鎖的狀態下調用,否則會拋出監控器狀態異常的異常。
還有為什么這三個方法要定義在Object中?
實例一段代碼:
public void run() { synchronized(this){ try { this.wait(); } catch (InterruptedException e) { e.PRintStackTrace(); } this.notify(); } }這三個方法的調用,默認會在前面加上鎖對象的引用,而鎖對象可以是任意對象,所以這三個方法應該可以被任意對象調用,被任意對象可以調用的方法必定定義在Object中。notify和notifyAll方法的注意點:
notify和notifyAll喚醒的都是它的對象鎖的鎖池中的線程。注意鎖不一樣,是無法喚醒對方的鎖池中的線程的。
新聞熱點
疑難解答