Thread.yield()詳解

(1)首先介紹線程運行狀態轉換,如下圖:

  1. 新建狀態(New):新創建了一個線程對象。

  2. 就緒狀態(可執行狀態,Runnable):線程對象創建後,其他線程調用了該對象的start()方法。該狀態的線程位於可運行線程池中,變得可運行,等待獲取CPU的使用權。

  3. 運行狀態(運行狀態,Running):就緒狀態的線程獲取了CPU,執行程序代碼。

  4. 阻塞狀態(Blocked):阻塞狀態是線程因爲某種原因放棄CPU使用權,暫時停止運行。直到線程進入就緒狀態,纔有機會轉到運行狀態。阻塞的情況分三種:

    (1) 等待阻塞:運行的線程執行wait()方法,該線程進入等待池中                   

    (2) 同步阻塞:運行的線程在獲取對象的同步鎖時,若該同步鎖被別的線程佔用,則該線程進入鎖池中

    (3) 其他阻塞:運行的線程執行sleep()或join()方法,或者發出了I/O請求時,該線程置爲阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程重新轉入就緒狀態。

  5. 死亡狀態(Dead):線程執行完了或者因異常退出了run()方法,該線程結束生命週期。

(2)理解線程的優先權

接下來,理解線程優先級是很重要的一步,尤其是瞭解 yield() 函數的工作過程:

1、記住當線程的優先級沒有指定時,所有線程都攜帶普通優先級。
2、優先級可以用從 1 到 10 的範圍指定。10 表示最高優先級,1 表示最低優先級,5 是普通優先級。
3、記住優先級最高的線程在執行時被給予優先。但是不能保證線程在啓動時就進入運行狀態。
4、與在線程池中等待運行機會的線程相比,當前正在運行的線程可能總是擁有更高的優先級。
5、由調度程序決定哪一個線程被執行。
6、t.setPriority() 用來設定線程的優先級。
7、記住在線程 start() 方法被調用之前,線程的優先級應該被設定。
8、你可以使用常量,如 MIN_PRIORITY,MAX_PRIORITY,NORM_PRIORITY 來設定優先級。


(3)Thread.yield 

  方法作用: 讓當前線程從運行狀態 轉爲 就緒狀態,以允許具有相同優先級的其他線程獲得運行機會

(4)代碼示例:

public class Yield {
    public static void main(String[] args) {
        Thread[] threads = new Thread[2];

        for (int i=0;i<2;i++){
            int index=i;
            threads[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                        System.out.println("threads"+index+":"+1);
                        Thread.yield();
                        System.out.println("threads"+index+":"+2);
                }
            });
            threads[i].start();
        }

    }
}

多次運行會如下結果:

threads0:1
threads1:1
threads0:2
threads1:2

或者

threads0:1
threads0:2
threads1:1
threads1:2

結論:無法保證yield()達到讓步目的,因爲讓步的線程還有可能被線程調度程序再次選中。

(5)總結如下幾點

1、yield 是一個靜態的原生(native)方法。

2、yield 告訴當前正在執行的線程把運行機會交給線程池中擁有相同優先級的線程。

3、yield 不能保證使得當前正在運行的線程迅速轉換到可運行的狀態。

4、它僅能使一個線程從運行狀態轉到可運行狀態,而不是等待或阻塞狀態。

5、無法保證yield()達到讓步目的,因爲讓步的線程還有可能被線程調度程序再次選中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章