官术网_书友最值得收藏!

1.6 讓出CPU執行權的yield方法

Thread類中有一個靜態的yield方法,當一個線程調用yield方法時,實際就是在暗示線程調度器當前線程請求讓出自己的CPU使用,但是線程調度器可以無條件忽略這個暗示。我們知道操作系統是為每個線程分配一個時間片來占有CPU的,正常情況下當一個線程把分配給自己的時間片使用完后,線程調度器才會進行下一輪的線程調度,而當一個線程調用了Thread類的靜態方法yield時,是在告訴線程調度器自己占有的時間片中還沒有使用完的部分自己不想使用了,這暗示線程調度器現在就可以進行下一輪的線程調度。

當一個線程調用yield方法時,當前線程會讓出CPU使用權,然后處于就緒狀態,線程調度器會從線程就緒隊列里面獲取一個線程優先級最高的線程,當然也有可能會調度到剛剛讓出CPU的那個線程來獲取CPU執行權。下面舉一個例子來加深對yield方法的理解。

public class YieldTest implements Runnable {
    YieldTest() {
      //創建并啟動線程
      Thread t = new Thread(this);
      t.start();
  }
  public void run() {
      for (int i = 0; i < 5; i++) {
        //當i=0時讓出CPU執行權,放棄時間片,進行下一輪調度
        if ((i % 5) == 0) {
            System.out.println(Thread.currentThread() + "yield cpu...");
          //當前線程讓出CPU執行權,放棄時間片,進行下一輪調度
          // Thread.yield();
          }
      }
      System.out.println(Thread.currentThread() + " is over");
  }
  public static void main(String[] args) {
      new YieldTest();
      new YieldTest();
      new YieldTest();
    }
}

輸出結果如下。

如上代碼開啟了三個線程,每個線程的功能都一樣,都是在for循環中執行5次打印。運行多次后,上面的結果是出現次數最多的。解開Thread.yield()注釋再執行,結果如下。

從結果可知,Thread.yield()方法生效了,三個線程分別在i=0時調用了Thread.yield()方法,所以三個線程自己的兩行輸出沒有在一起,因為輸出了第一行后當前線程讓出了CPU執行權。

一般很少使用這個方法,在調試或者測試時這個方法或許可以幫助復現由于并發競爭條件導致的問題,其在設計并發控制時或許會有用途,后面在講解java.util.concurrent. locks包里面的鎖時會看到該方法的使用。

總結:sleep與yield方法的區別在于,當線程調用sleep方法時調用線程會被阻塞掛起指定的時間,在這期間線程調度器不會去調度該線程。而調用yield方法時,線程只是讓出自己剩余的時間片,并沒有被阻塞掛起,而是處于就緒狀態,線程調度器下一次調度時就有可能調度到當前線程執行。

主站蜘蛛池模板: 浠水县| 临桂县| 合江县| 玉溪市| 梧州市| 玛沁县| 溆浦县| 德惠市| 仁寿县| 高淳县| 岚皋县| 长寿区| 桦川县| 海口市| 西乌珠穆沁旗| 黄浦区| 沙坪坝区| 南溪县| 崇信县| 宿迁市| 海南省| 名山县| 新乡县| 巨野县| 通许县| 讷河市| 永清县| 巴彦淖尔市| 无锡市| 临夏县| 三江| 广南县| 汉寿县| 鄂州市| 新郑市| 始兴县| 平乡县| 云安县| 抚顺县| 会理县| 同江市|