如果處於就緒狀態的執行緒獲得了cpu
,開始執行run()
方法的執行緒執行體,則該執行緒處於執行狀態
,如果計算機只有乙個cpu
,那麼在任何時刻只有乙個執行緒處於執行狀態。當然,在乙個多處理器的機器上,將會有多個執行緒並行
執行;不過當執行緒數大於處理器數時,依然會存在多個執行緒在同乙個cpu
上輪換的現象。(注意多處理器的機器上是並行:parallel
,單處理器上是併發
)
當乙個執行緒開始執行後,它不可能一直處於執行狀態(除非它的執行緒執行體足夠短,瞬間就執行結束了),執行緒在執行過程中需要被中斷,目的是使其他執行緒獲得執行的機會,執行緒排程的細節取決於底層平台所採用的策略。對於採用搶占式策略
的系統而言,系統會給每個可執行的執行緒乙個小時間段
來處理任務;當該時間段用完後,系統就會剝奪該執行緒所占用的資源,讓其他執行緒獲得執行的機會。在選擇下乙個執行緒時,系統會考慮執行緒的優先順序。
所有現代的桌面和伺服器作業系統都採用搶占式排程策略
,但一些小型裝置如手機
則可能採用協作式排程策略
,在這樣的系統中,只有當乙個執行緒呼叫了它的sleep()
或yield()
方法後才會放棄所占用的資源,也就是必須由該執行緒主動放棄所占用的資源。
當發生如下情況時,執行緒將會進入阻塞狀態。
執行緒呼叫sleep()
方法主動放棄所占用的處理器資源。
執行緒呼叫了乙個阻塞式io方法
,在阻塞式io方法
返回之前,該執行緒被阻塞。
執行緒試圖獲得乙個同步監視器,但該同步監視器正被其他執行緒所持有的時候
。
執行緒在等待某個通知(notify
)。
程式呼叫了執行緒的suspend()
方法將該執行緒掛起。但這個方法容易導致死鎖,所以應該盡量避免使用該方法。
當前正在執行的執行緒被阻塞之後,其他執行緒就可以獲得執行的機會。被阻塞的執行緒會在合適的時候重新進入就緒狀態
,注意是就緒狀態
而不是執行狀態。也就是說,被阻塞執行緒的阻塞解除後,必須重新等待執行緒排程器再次排程它。
針對上面幾種情況,當發生如下特定的情況時可以解除上面的阻塞,讓該執行緒重新進入就緒狀態。
呼叫sleep
方法的執行緒經過了指定時間
執行緒呼叫的阻塞式io方法
已經返回。
執行緒成功地獲得了試圖取得的同步監視器。
執行緒正在等待某個通知時,其他執行緒發出了乙個通知
。
處於掛起狀態的執行緒被呼叫了resumed()
恢復方法。
圖16.4顯示了執行緒狀態轉換圖。
從圖16.4中可以看出,執行緒從阻塞狀態
只能進入就緒狀態
,無法直接進入執行狀態。而就緒狀態和執行狀態之間的轉換通常不受程式控制,而是由系統執行緒排程所決定,當處於就緒狀態的執行緒獲得處理器資源時,該執行緒進入執行狀態;當處於執行狀態的執行緒失去處理器資源時,該執行緒進入就緒狀態。但有個方法例外,呼叫yield()
方法可以讓執行狀態的執行緒轉入就緒狀態。
執行緒 執行和阻塞狀態詳解
所有現代的桌面和伺服器作業系統都採用搶占式排程策略,但一些小型裝置如手機等可能採用協作式排程策略,在這樣的系統中,只有當乙個執行緒呼叫了它的sleep 或yield 方法後才會放棄其所占用的資源 也就是必須有執行緒主動放棄其所占用的資源。當發生如下情況時,執行緒將進入阻塞狀態 1 執行緒呼叫了sle...
檔案非阻塞狀態開啟後改變為阻塞狀態
所以如果開啟檔案時是用非阻塞狀態開啟的 open dev tty o rdwr o noctty o ndelay 則可以用fcntl改變檔案狀態標誌 fcntl fd,f setfl,0 改變檔案為阻塞狀態。或者麻煩點,但易於理解 1 獲取檔案的flags,即open函式的第二個引數 flags ...
執行緒阻塞狀態例項分析
有三種方法可以暫停threads執行 1.sleep方法 sleep時別的執行緒也不可以訪問鎖定物件。2.yield方法 讓出cpu的使用權,從執行態直接進入就緒狀態。讓cpu重新挑選哪乙個執行緒進入執行狀態。3.join方法 當某乙個執行緒等待另乙個執行緒執行結束後,才繼續執行時,使用join方法...