- Java并發編程之美
- 翟陸續 薛賓田
- 820字
- 2019-07-25 11:54:00
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方法時,線程只是讓出自己剩余的時間片,并沒有被阻塞掛起,而是處于就緒狀態,線程調度器下一次調度時就有可能調度到當前線程執行。
- Java語言程序設計
- 數字媒體應用教程
- PaaS程序設計
- Python自動化運維快速入門
- 程序員數學:用Python學透線性代數和微積分
- JMeter 性能測試實戰(第2版)
- 跟老齊學Python:輕松入門
- Python高級機器學習
- PySide GUI Application Development(Second Edition)
- Learning Python Design Patterns
- AppInventor實踐教程:Android智能應用開發前傳
- Swift 4從零到精通iOS開發
- Scala Data Analysis Cookbook
- Getting Started with Polymer
- Hands-On Robotics Programming with C++