Posted on 2009-02-25 11:09
love1563 閱讀(1707)
評論(0) 編輯 收藏 所屬分類:
Java語言*高級版
1 線程狀態
線程可以有一下4個狀態:
· New (新生)
·Runnable(可運行)
·Blocked(被阻塞)
· Dead(死亡)
1.1 新生線程
當你new操作符創建一個線程時,new thread(r),線程還沒開始運行,此時線程處在新生(new)狀態。當一個線程出于新生狀態時,程序還沒有開始運行線程中的代碼。在程序開始運行之前還又一些簿記工作要做。
1.2 可運行的線程
一旦調用了start方法,該線程就成為可運行的(Runnable)了。一個可運行線程可能實際上正在運行,也可能沒有,這取決于操作系統為該線程提供的運行時間。
一旦線程開始運行,它不需要始終保持運行。事實上,線程在運行過程中有時需要被中斷,目的是使其他線程獲得運行的機會,線程調度的細節取決于操作系統所提供的服務。如:搶占式調度的系統給每個可運行的線程一個時間片來處理任務。當這個時間片用完時,操作系統剝奪該線程對資源的占用,使其他線程有機會運行。在選擇下一個線程時,操作系統會考慮線程的優先級。
所有現在的桌面和服務器操作系統都使用搶占式調度。但一些小型設備,如:手機,可能采用協作式調度。在這樣的設備中,一個線程只有在調度sleep或者yield這樣的方法時才會丟失控制權。
一個多處理器的機器上,每個處理器都可以運行一個線程,你可以使多個線程并行運行。當然如果線程的個數大于處理器的個數,那么調度器將仍舊采用時間片機制。
在任何給定的時刻,一個可運行線程可能正在運行,也可能不是。(這正式為什么把這個狀態成為runnable,而不是running)。
1.3 被阻塞線程
當發生一下任何一種情況時,線程就進入被阻塞狀態:
·線程通過調用sleep方法進入睡眠狀態;
·線程調用一個在I/O上被阻塞的操作,即該操作在輸入輸出操作完成之前不會返回到它的調用者;
·線程試圖得到一個鎖,而該鎖正被其他線程持有。
·線程正等待某個觸發條件;
如上圖顯示,線程的各種裝填及狀態之間的轉化關系。當一個線程被阻塞(或者,當它死亡時),另一個線程就可以被調度欲行了。當一個被阻塞的線程重新被激活時(例如,由于它的睡眠時間已經到達了制定的毫秒數或者因為它等待I/O已經完成),調度器檢查它的優先級是否高于當前的運行線程,如果是,它就將搶占當前線程的資源并開始運行。
通過一下幾種途徑中的一種,線程可以從被阻塞狀態到可運行狀態。
1)線程被置于睡眠狀態,且已經經過指定的毫秒數。
2)線程正在等待I/O操作的完成,且該操作已經完成。
3)線程正在等待另一個線程所持有的鎖,且另一個線程已經釋放該鎖的所有權;(也有可能等待超時。當超時發生時,線程解除阻塞。)
4)線程正在等待某個觸發條件,且另一個線程發出了信號表明條件已經發生了變化。(如果為線程的等待設置了一個超時,那么當超時發生時該線程將解除阻塞。)
5)線程已經被掛起,且有人調用了它的resume方法。不過,由于suspend方法已經過時,resume方法也就隨之被棄用了,你不應該在自己的代碼里調用它。
一個被阻塞的線程只能通過和先前阻塞它的相同的過程重新進入可運行狀態。要特別注意,你不能通過調用resume方法來解除被阻塞線程的阻塞狀態。