線程優先順序
線程的優先順序將該線程的重要性傳遞給線程調度器,調度器將傾向於讓優先權最高的線程先執行.然後這並不意味值優先權較低的線程將得不到執行.優先順序較低的線程僅僅是執行的頻率較低
package com.yin.myproject.demo.concurrent.base;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class SimplePriorities implements Runnable { private int countDown = 5; private volatile double d; private int priority; public SimplePriorities(int priority) { this.priority = priority; } public String toString() { return "name:" + Thread.currentThread().getName() + " priority: " + Thread.currentThread().getPriority() + ":prority:" + ": " + countDown; } public void run() { Thread.currentThread().setPriority(priority); while (true) { for (int i = 1; i < 10000; i++) { d += (Math.PI + Math.E) / (double) i; if (i % 1000 == 0) { Thread.yield(); } } System.out.println(this); if (--countDown == 0) return; } } public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); for (int i = 0; i < 5; i++) { exec.execute(new SimplePriorities(Thread.MIN_PRIORITY)); exec.execute(new SimplePriorities(Thread.MAX_PRIORITY)); } exec.shutdown(); }}
輸出結果(每次執行結果都會有所偏差):
name:pool-1-thread-6 priority: 10: 5name:pool-1-thread-3 priority: 1: 5name:pool-1-thread-4 priority: 1: 5name:pool-1-thread-1 priority: 1: 5name:pool-1-thread-5 priority: 1: 5name:pool-1-thread-2 priority: 1: 5name:pool-1-thread-1 priority: 1: 4name:pool-1-thread-6 priority: 10: 4name:pool-1-thread-4 priority: 1: 4name:pool-1-thread-3 priority: 1: 4......
從執行結果上我們可以總結為一下兩點:
1. 線程優先順序並不能保證線程的執行順序,優先順序高的並不一定先執行,優先順序低的也不一定不執行
2. 不要試圖使用優先順序來控制線程的執行順序 yield()函數
首先看一下官方文檔的解釋:
A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.
大體意思是說,當調用Thread.yield()函數時,會給線程調度器一個當前線程願意讓出CPU使用的暗示,但是線程調度器可能會忽略這個暗示。通俗的解釋就是當前線程願意讓出CPU的使用權,可以讓其他線程繼續執行,但是線程調度器可能會停止當前線程繼續執行,也可能會讓該線程繼續執行。
下面通過一個例子來示範Thread.yield()函數的使用:
public class YieldDemo01 { public static void main(String[] args) { YieldThread t1 = new YieldThread("線程一"); YieldThread t2 = new YieldThread("線程二"); t1.start(); t2.start(); }}class YieldThread extends Thread { private String name; public YieldThread(String name) { this.name = name; } @Override public void run() { for (int i = 1; i <= 10; i++) { System.out.println(name + i); if (i == 5) { Thread.yield(); } } }}
每次啟動並執行結果都可能會有偏差,但是注意線程一5和線程二5之後的執行結果。
另一種理解:在網上還存在另一種理解,當調用Thread.yield()函數後,當前線程會被停止,繼而其他線程會爭奪cpu的控制權,因此有可能是當前線程獲得執行,也可能其他線程獲得執行. 根據官方文檔和Thinking In Java上的講解,可以確定這種理解是錯誤的.當調用Thread.yiele()時,沒有任何機制可以保證當前線程一定會被停止 總結
可以看出,不管優先順序和yield()函數都是試圖控制線程的順序執行.但是我們需要注意的一點是,在java中沒有任何機制可以保證線程的執行順序,兩種做法只不過是增加了線程之間切換的幾率而已.