二級Java考試輔導教程:6.1線程簡介[3]

字號:

仔細分析一下運行結(jié)果,會發(fā)現(xiàn)兩個線程是交錯運行的,感覺就象是兩個線程在同時運行。但是實際上一臺計算機通常就只有一個CPU,在某個時刻只能是只有一個線程在運行,而java語言在設計時就充分考慮到線程的并發(fā)調(diào)度執(zhí)行。對于程序員來說,在編程時要注意給每個線程執(zhí)行的時間和機會,主要是通過讓線程睡眠的辦法(調(diào)用sleep()方法)來讓當前線程暫停執(zhí)行,然后由其它線程來爭奪執(zhí)行的機會。如果上面的程序中沒有用到sleep()方法,則就是第一個線程先執(zhí)行完畢,然后第二個線程再執(zhí)行完畢。所以用活sleep()方法是學習線程的一個關(guān)鍵。
    構(gòu)造線程體的兩種方法的比較:
    1. 使用Runnable接口
    1) 可以將CPU,代碼和數(shù)據(jù)分開,形成清晰的模型;
    2) 還可以從其他類繼承;
    3) 保持程序風格的一致性。
    2. 直接繼承Thread類
    1) 不能再從其他類繼承;
    2) 編寫簡單,可以直接操縱線程,無需使用Thread.currentThread()。
    6.1.3 線程的調(diào)度
    Java提供一個線程調(diào)度器來監(jiān)控程序中啟動后進入就緒狀態(tài)的所有線程。線程調(diào)度器按照線程的優(yōu)先級決定應調(diào)度哪些線程來執(zhí)行。 來源:www.examda.com
    線程調(diào)度器按線程的優(yōu)先級高低選擇高優(yōu)先級線程(進入運行中狀態(tài))執(zhí)行,同時線程調(diào)度是搶先式調(diào)度,即如果在當前線程執(zhí)行過程中,一個更高優(yōu)先級的線程進入可運行狀態(tài),則這個線程立即被調(diào)度執(zhí)行。
    搶先式調(diào)度又分為:時間片方式和獨占方式。在時間片方式下,當前活動線程執(zhí)行完當前時間片后,如果有其他處于就緒狀態(tài)的相同優(yōu)先級的線程,系統(tǒng)會將執(zhí)行權(quán)交給其他就緒態(tài)的同優(yōu)先級線程;當前活動線程轉(zhuǎn)入等待執(zhí)行隊列,等待下一個時間片的調(diào)度。
    在獨占方式下,當前活動線程一旦獲得執(zhí)行權(quán),將一直執(zhí)行下去,直到執(zhí)行完畢或由于某種原因主動放棄CPU,或者是有一高優(yōu)先級的線程處于就緒狀態(tài)。
    下面幾種情況下,當前線程會放棄CPU:
    1. 線程調(diào)用了yield() 或sleep() 方法主動放棄;
    2. 由于當前線程進行I/O 訪問,外存讀寫,等待用戶輸入等操作,導致線程阻塞;或者是為等候一個條件變量,以及線程調(diào)用wait()方法;
    3. 搶先式系統(tǒng)下,由高優(yōu)先級的線程參與調(diào)度;時間片方式下,當前時間片用完,由同優(yōu)先級的線程參與調(diào)度。
    線程的優(yōu)先級
    線程的優(yōu)先級用數(shù)字來表示,范圍從1到10,即Thread.MIN_PRIORITY到Thread.MAX_PRIORITY。一個線程的缺省優(yōu)先級是5,即Thread.NORM_PRIORITY。下述方法可以對優(yōu)先級進行操作:
    int getPriority(); //得到線程的優(yōu)先級
    void setPriority(int newPriority);
    //當線程被創(chuàng)建后,可通過此方法改變線程的優(yōu)先級
    例6.3中生成三個不同線程,其中一個線程在最低優(yōu)先級下運行,而另兩個線程在優(yōu)先級下運行。
    6.1.4基本的線程控制
    1.終止線程
    線程終止后,其生命周期結(jié)束了,即進入死亡態(tài),終止后的線程不能再被調(diào)度執(zhí)行,以下幾種情況,線程進入終止狀態(tài):
    1) 線程執(zhí)行完其run()方法后,會自然終止。
    2) 通過調(diào)用線程的實例方法stop()來終止線程。
    2. 測試線程狀態(tài)
    可以通過Thread 中的isAlive() 方法來獲取線程是否處于活動狀態(tài);線程由start() 方法啟動后,直到其被終止之間的任何時刻,都處于’Alive’狀態(tài)。
    3. 線程的暫停和恢復
    有幾種方法可以暫停一個線程的執(zhí)行,在適當?shù)臅r候再恢復其執(zhí)行。
    1) sleep() 方法
    當前線程睡眠(停止執(zhí)行)若干毫秒,線程由運行中狀態(tài)進入不可運行狀態(tài),停止執(zhí)行時間到后線程進入可運行狀態(tài)。
    2) suspend()和resume()方法
    線程的暫停和恢復,通過調(diào)用線程的suspend()方法使線程暫時由可運行態(tài)切換到不可運行態(tài),若此線程想再回到可運行態(tài),必須由其他線程調(diào)用resume()方法來實現(xiàn)。
    注:從JDK1.2開始就不再使用suspend()和resume()。
    3) join()
    當前線程等待調(diào)用該方法的線程結(jié)束后, 再恢復執(zhí)行.
    TimerThread tt=new TimerThread(100);
    tt.start();
    …
    public void timeout(){
    tt.join();// 當前線程等待線程tt 執(zhí)行完后再繼續(xù)往下執(zhí)行
    … }