Java 多线程:线程优先级
1 優先級取值范圍
Java 線程優先級使用 1 ~ 10 的整數表示:
-
最低優先級 1:Thread.MIN_PRIORITY
-
最高優先級 10:Thread.MAX_PRIORITY
-
普通優先級 5:Thread.NORM_PRIORITY
2 獲取線程優先級
public static void main(String[] args) {System.out.println(Thread.currentThread().getPriority()); }運行結果:
3 設置優先級
Java 使用 setPriority 方法設置線程優先級,方法簽名
public final void setPriority(int newPriority)示例:
public static void main(String[] args) {Thread.currentThread().setPriority(Thread.MIN_PRIORITY);System.out.println(Thread.currentThread().getPriority());Thread.currentThread().setPriority(Thread.MAX_PRIORITY);System.out.println(Thread.currentThread().getPriority());Thread.currentThread().setPriority(8);System.out.println(Thread.currentThread().getPriority()); }運行結果:
newPriority 設置范圍在 1-10,否則拋出 java.lang.IllegalArgumentException 異常
public static void main(String[] args) {Thread.currentThread().setPriority(0);System.out.println(Thread.currentThread().getPriority()); }運行結果:
4 默認線程優先級
Java 默認的線程優先級是父線程的優先級,而非普通優先級Thread.NORM_PRIORITY,因為主線程默認優先級是普通優先級Thread.NORM_PRIORITY,所以如果不主動設置線程優先級,則新創建的線程的優先級就是普通優先級Thread.NORM_PRIORITY
class CustomThread extends Thread {@Overridepublic void run() {System.out.println("父線程優先級:" + this.getPriority());Thread t = new Thread(new CustomRunnable());System.out.println("子線程優先級:" + t.getPriority());} }class CustomRunnable implements Runnable {@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println("CustomRunnable : " + i);}} }public static void main(String[] args) {Thread t = new CustomThread();t.setPriority(3);t.start(); }運行結果:
5 線程調度
高優先級的線程比低優先級的線程有更高的幾率得到執行,實際上這和操作系統及虛擬機版本相關,有可能即使設置了線程的優先級也不會產生任何作用。
class CustomThread extends Thread {public CustomThread(String name) {super(name);}@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + " : " + i);}} }public static void main(String[] args) {Thread t1 = new CustomThread("A");Thread t2 = new CustomThread("B");t1.setPriority(Thread.MIN_PRIORITY);t2.setPriority(Thread.MAX_PRIORITY);t1.start();t2.start(); }運行結果:
6 線程組的最大優先級
我們可以設定線程組的最大優先級,當創建屬于該線程組的線程時,新線程的優先級不能超過這個最大優先級
-
系統線程組的最大優先級默認為 Thread.MAX_PRIORITY
-
創建線程組時最大優先級默認為父線程組(如果未指定父線程組,則其父線程組默認為當前線程所屬線程組)的最大優先級
-
可以通過 setPriority 更改最大優先級,但無法超過父線程組的最大優先級
7 setPriority 注意事項
該方法只能更改本線程組及其子線程組(遞歸)的最大優先級,但不能影響已經創建的直接或間接屬于該線程組的線程的優先級,也就是說,即使目前有一個子線程的優先級比新設定的線程組優先級大,也不會更改該子線程的優先級。只有當試圖改變子線程的優先級或者創建新的子線程的時候,線程組的最大優先級才起作用
8 線程優先級的問題
-
Thread.setPriority() 是否起作用和操作系統及虛擬機版本相關
-
線程優先級對于不同的線程調度器可能有不同的含義,可能并不是你直觀的推測。特別地,優先級并不一定是指CPU的分享。在UNIX系統,優先級或多或少可以認為是CPU的分配,但Windows不是這樣
-
線程的優先級通常是全局的和局部的優先級設定的組合。Java的 setPriority() 方法只應用于局部的優先級。換句話說,你不能在整個可能的范圍內設定優先級,這通常是一種保護的方式,你大概不希望鼠標指針的線程或者處理音頻數據的線程被其它隨機的用戶線程所搶占
-
不同的系統有不同的線程優先級的取值范圍,但是Java定義了10個級別(1-10)。這樣就有可能出現幾個線程在一個操作系統里有不同的優先級,在另外一個操作系統里卻有相同的優先級,并因此可能有意想不到的行為
-
操作系統可能(并通常這么做)根據線程的優先級給線程添加一些專有的行為,如 only give a quantum boost if the priority is below X,這里再重復一次,優先級的定義有部分在不同系統間有差別
-
大多數操作系統的線程調度器實際上執行的是在戰略的角度上對線程的優先級做臨時操作,例如當一個線程接收到它所等待的一個事件或者 I/O,通常操作系統知道最多,試圖手工控制優先級可能只會干擾這個系統
-
應用程序通常不知道有哪些其它運行的線程,所以對于整個系統來說,變更一個線程的優先級所帶來的影響是難于預測的,例如有一個預期為偶爾在后臺運行的低優先級的線程幾乎沒有運行,原因是一個病毒監控程序在一個稍微高一點的優先級(但仍然低于普通的優先級)上運行,并且無法預計你程序的性能,它會根據你的客戶使用的防病毒程序不同而不同
總結
以上是生活随笔為你收集整理的Java 多线程:线程优先级的全部內容,希望文章能夠幫你解決所遇到的問題。