線程的優先級(priority)決定了線程獲得CPU運作的機會,優先級越高獲得的運作機會越大,優先級越低獲得的機會越小.Java的線程有10個級别(準确的說是11個級别,級别為0的線程是JVM,應用程式不能設定該級别)
那是不是級别為10的線程肯定比級别為9的線程優先運作呢?
看代碼:
1 public class Client {
2 public static void main(String[] args){
3 //啟動20個不同優先級的線程
4 for (int i = 0; i < 20; i++) {
5 new TestThread().start(i % 10 + 1);
6 }
7
8 }
9 }
10
11 class TestThread implements Runnable {
12 //啟動線程
13 public void start(int _priority) {
14 Thread t = new Thread(this);
15 //設定線程優先級
16 t.setPriority(_priority);
17 t.start();
18 }
19
20 @Override
21 public void run() {
22 //消耗CPU的計算,性能差的機器,請修改循環限制
23 for (int i = 0; i < 100000; i++) {
24 Math.hypot(Math.pow(924526789,i),Math.cos(i));
25 }
26 //輸出線程優先級
27 System.out.println("Priority:" + Thread.currentThread().getPriority());
28
29 }
30 }
該多線程類實作了Runnable接口,實作了run方法,注意在run方法中有一個比較占用CPU的計算,該計算毫無意義,隻是為了保證一個線程盡可能多的消耗CPU資源,目的是為了觀察在CPU繁忙時,不同優先級線程的執行順序.
需要說明的是,如果此處使用了Thread.sleep()方法,則不能展現出線程優先級的本質了,因為CPU并不繁忙,線程排程不會遵循優先級順序來進行排程.
上面代碼建立了20個線程,每個線程在運作時都耗盡了CPU資源,因為優先級不同,線程排程應該最先處理優先級最高的,然後處理優先級最低的,也就是先執行了2個優先級為10的線程,然後執行2個優先級為9的線程,2個優先級為8的線程....是結果并不是這樣的...
運作結果:
Priority:10
Priority:7
Priority:1
Priority:8
Priority:3
Priority:6
Priority:3
Priority:2
Priority:4
Priority:8
Priority:9
Priority:9
Priority:10
Priority:2
Priority:6
Priority:7
Priority:5
Priority:5
Priority:4
Priority:1
println方法雖然有輸出損耗,可能會影響到輸出結果,但是不管運作多少次,都有兩個不争的事實.
(1)并不是嚴格遵守線程優先級别來執行的.
因為優先級隻是代表獲得CPU運作的機會,并不代表強制的排序号.
(2)優先級差别越大,運作機會差别越明顯.
比如優先級為10的線程通常比優先級為2的線程先執行,但是優先級為6的線程和優先級為5的線程差别就不太明顯了.
這連個現象是優先級的一個重要表現:
因為線程運作是要獲得CPU資源的,誰能決定哪個線程先獲得哪個線程後獲得呢?
這是依照作業系統設定的線程優先級來配置設定的,每個線程需要運作,需要作業系統配置設定優先級和CPU資源,對Java來說,JVM調用作業系統的接口設定優先級,比如Windows作業系統是通過調用SetThreadPriority函數來設定的.
不同的作業系統線程的優先級是不相同的,Windows7個優先級,Linux有140個優先級,Freebsd則有255個(此處指的是優先級總數,不同作業系統有不同的分類,如中斷線程,作業系統等級等,各個作業系統具體使用者可用的線程數量也不相同).
Java是跨平台的系統,需要把10個優先級映射成不同作業系統的優先級,于是界定了Java的優先級隻是代表搶占CPU的機會大小,優先級越高,搶占CPU的機會越大.被執行的可能性越高.
Java的締造者們也發現了這個問題,于是在Thread類中設定了三個優先級,建議使用優先級常量,而不是1到10的随機數字.
public class Thread implements Runnable {
/**
* The minimum priority that a thread can have.
*/
public final static int MIN_PRIORITY = 1;
/**
* The default priority that is assigned to a thread.
*/
public final static int NORM_PRIORITY = 5;
/**
* The maximum priority that a thread can have.
*/
public final static int MAX_PRIORITY = 10;
}
建議使用這三個級别,不建議使用其他7個數字.
如果優先級相同,怎麼辦?
這也是由作業系統決定的,基本上是按照FIFO的原則,但是也不能完全保證.
作者:SummerChill |