線程的狀態轉換

一個線程創建之後,總是處於其生命週期的4個狀態之一中。線程的狀態表明此線 程當前正在進行的活動,而線程的狀態是可以通過程序來進行控制的,就是說,可以對線程 進行操作來改變狀態。這些操作包括啓動(start)、終止(stop)、睡眠(sleep)、掛起 (suspend)、恢復(resume)、等待(wait)和通知(notify)。每一個操作都對應了一個方法,這些 方法是由軟件包java.lang提供的。
①創建(new)狀態
如果創建了一個線程而沒有啓動它,那麼,此線程就處於創建狀態。比如,下述語句執行 以後,使系統有了一個處於創建狀態的線程myThread:
Thread myThread= new MyThreadClass();
其中,MyThreadClass()是Thread的子類,而Thread是由Java系統的java.lang軟件包提 供的。
處於創建狀態的線程還沒有獲得應有的資源,所以,這是一個空的線程。線程只有通過 啓動後,系統纔會爲它分配資源。對處於創建狀態的線程可以進行兩種操作:一是啓動 (start)操作,使其進入可運行狀態,二是終止(stop)操作,使其進入消亡狀態。如果進入到消 亡狀態,那麼,此後這個線程就不能進入其他狀態,也就是說,它不再存在了。
start方法是對應啓動操作的方法,其具體功能是爲線程分配必要的系統資源;將線程 設置爲可運行狀態,從而可以使系統調度這個線程。
②可運行(runnable)狀態
如果對一個處於創建狀態的線程進行啓動操作,則此線程便進入可運行狀態。仍以前面 創建的myThread線程爲例,用下列語句: myThread.start(); 則線程myThread進入可運行狀態。上述語句實質上是調用了線程體即run()方法。注意, run()方法包含在myThread線程中,也就是先由java.lang包的Thread類將run()方法 傳遞給子類MyThreadClass(),再通過創建線程由於類MyThreadClass()傳遞給線程 myThread。
線程處於可運行狀態只說明它具備了運行條件,但可運行狀態並不一定是運行狀態。因 爲在單處理器系統中運行多線程程序,實際上在一個時間點只有一個線程在運行,而系統中 往往有多個線程同時處於可運行狀態。系統通過快速切換和調度使所有可運行線程共享處 理器,造成宏觀上的多線程併發運行。
可見,一個線程是否處於運行狀態,除了必須處於可運行狀態外,還取決於系統的調度。
在可運行狀態可以進行多種操作,最通常的是從run()方法正常退出而使線程結束,進 入消亡狀態。此外,還可以有如下操作:
掛起操作,通過調用suspend方法來實現;
睡眠操作,通過調用sleep方法來實現;
等待操作,通過調用wait方法來實現;
退讓操作,通過調用yield方法來實現;
終止操作,通過調用stop方法來實現。
前面三種操作都會使一個處於可運行狀態的線程進入不可運行狀態。比如,仍以 myThread線程爲例,當其處於可運行狀態後,再用如下語句:
myThreadsleep(5000);
則調用sleep方法使myThread線程睡眠5秒(5000毫秒)。這5秒內,此線程不能被系統調 度運行,只有過5秒後,myThread線程纔會醒來並自動回到可運行狀態。
如果一個線程被執行掛起操作而轉到不可運行狀態,則必須通過調用恢復(resume)操 作,才能使這個線程再回到可運行狀態。
退讓操作是使某個線程把CPU控制權提前轉交給同級優先權的其他線程。
對可運行狀態的線程也可以通過調用stop方法使其進入消亡狀態。
③不可運行(not runnable)狀態
不可運行狀態都是由可運行狀態轉變來的。一個處於可運行狀態的線程,如果遇到掛起 (suspend)操作、睡眠(sleep)操作或者等待(wait)操作,就會進入不可運行狀態。另外,如果 一個線程是和I/O操作有關的,那麼,在執行I/O指令時,由於外設速度遠遠低於處理器速 度而使線程受到阻塞,從而進入不可運行狀態,只有外設完成輸入/輸出之後,該線程纔會自 動回到可運行狀態。線程進入不可運行狀態後,還可以再回到可運行狀態。通常有三種途徑 使其恢復到可運行狀態。
一是自動恢復。
通過睡眠(sleep)操作而進入不可運行狀態的線程會在過了指定睡眠時間以後自動恢 復到可運行狀態;由於I/O阻塞而進入不可運行狀態的線程在外設完成I/O操作後,自動 恢復到可運行狀態。
二是用恢復(resume)方法使其恢復。
如果一個線程由於掛起(suspend)操作而從可運行狀態進入不可運行狀態,那麼,必須 用恢復(resume)操作使其再恢復到可運行狀態。
三是用通知(notify或notiyA11)方法使其恢復。
如果一個處於可運行狀態的線程由於等待(wait)操作面轉入不可運行狀態,那麼,必須 通過調用notify方法或notifyAll方法才能使其恢復到可運行狀態。採用等待操作往往是由 於線程需要等待某個條件變量,當獲得此條件變量後,便可由notify或notifyAll方法使線 程恢復到可運行狀態。
恢復到可運行狀態的每一種途徑都是有針對性的,不能交叉。比如,對由於阻塞而進入 不可運行狀態的線程採用恢復操作將是無效的。
在不可運行狀態,也可由終止(stop)操作使其進入消亡狀態。
④消亡(dead)狀態
一個線程可以由其他任何一個狀態通過終止(stop)操作而進入消亡狀態。線程一旦進 入消亡狀態,那它就不再存在,所以也不可能再轉到其他狀態。
通常,在一個應用程序運行時,如果通過其他外部命令終止當前應用程序,那麼就會調 用stop方法終止線程。但是,最正常、最常見的途徑是由於線程在可運行狀態正常完成自身 的任務而“壽終正寢”,從而進入消亡狀態,這個完成任務的動作是由run方法實現的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章