Java線程設置了優先級,就必定生效嗎?Java線程的priority源碼解析

    歡迎你們關注個人公衆號"小猴子的技術筆記",有問題能夠及時和我交流。
    咱們知道在構建一個線程對象的時候能夠給線程設置一個優先級,就像下面這樣:安全

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("設置線程的優先級");
    }
}
public class MyRunnableTest {
    public static void main(String[] args) {
        Thread thread = new Thread(new MyRunnable());
        thread.setPriority(10);
        thread.start();
    }
}

    或許你曾經有過這樣的想法,若是有多個線程的話,是否是能夠按照這種優先級設置的順序來啓動線程呢?咱們來看下面這個例子:ide

public class MinPriority implements Runnable {
    @Override
    public void run() {
        System.out.println("線程的優先級爲1");
    }
}
public class NormalPriority implements Runnable {
    @Override
    public void run() {
        System.out.println("線程的優先級爲5");
    }
}
public class MaxPriority implements Runnable {
    @Override
    public void run() {
        System.out.println("線程的優先級爲10");
    }
}
public class ThreadPriorityTest {
    public static void main(String[] args) {
        Thread minThread = new Thread(new MinPriority());
        minThread.setPriority(1);
        Thread maxThread = new Thread(new MaxPriority());
        maxThread.setPriority(10);
        Thread normalThread = new Thread(new NormalPriority());
        normalThread.setPriority(5);
        minThread.start();
        maxThread.start();
        normalThread.start();
    }
}

    我模擬了三個不一樣優先級別的線程,在構建完成以後「同時」啓動,而後觀察結果。也請你嘗試把這些代碼拷貝到你的開發工具中,而後嘗試運行「ThreadPriorityTest」,也許第一次你看到的結果是這樣的:工具

線程的優先級爲10
線程的優先級爲5
線程的優先級爲1

    你會很開心,由於它按照你的預期來輸出了。可是,請嘗試多運行幾回「ThreadPriorityTest」你也許會發現有其餘的不一樣的結果:開發工具

線程的優先級爲5
線程的優先級爲10
線程的優先級爲1

    看到上面結果以後,回過頭來看咱們最初設置的線程的優先級貌似並無起到什麼做用。這究竟是爲何呢?彆着急!咱們先來過一遍設置線程優先級的源碼:線程

public final void setPriority(int newPriority) {
    ThreadGroup g;
    checkAccess();
    if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
        throw new IllegalArgumentException();
    }
    if((g = getThreadGroup()) != null) {
        if (newPriority > g.getMaxPriority()) {
            newPriority = g.getMaxPriority();
        }
        setPriority0(priority = newPriority);
    }
}

    首先聲明瞭一個線程組對象,而後「checkAccess()」進行了安全檢查,緊接着就是判斷咱們傳遞過來的優先級的值,判斷它是否是低於最小的優先級,高於最大的優先級,若是知足上述條件的話,就直接拋出參數不合法的異常。
線程Thread類提供了三個優先級的常量:code

// 可設置最小優先級
public final static int MIN_PRIORITY = 1;
// 默認的優先級,若是沒設置的話,默認爲此值
public final static int NORM_PRIORITY = 5;
// 可設置最大優先級
public final static int MAX_PRIORITY = 10;

    源碼中比較重要的就是「((g = getThreadGroup()) != null)」的判斷,第一步先經過「getThreadGroup()」方法獲取到當前的線程組賦值給「g」。獲取線程組「getThreadGroup()」方法的源碼以下:orm

public final ThreadGroup getThreadGroup() {
    return group;
}

    拿到返回的線程組以後判斷咱們顯示設置的線程優先級的值是否大於了線程組的優先級,若是大於了,就設置爲線程組的優先級。對象

    最後就是經過「setPriority0(priority = newPriority)」方法給線程賦值:開發

private native void setPriority0(int newPriority);

    能夠看到最後設置線程的這個方法是調用的本地方法,那麼就是交由底層去實現的。get

    其實線程的優先級設置能夠理解爲線程搶佔CPU時間片的機率,雖然機率比較大,可是它不必定就是按照優先級的順序去搶佔CPU時間片的,具體的執行順序仍是要根據誰先搶到了CPU的時間片,誰就先來執行。

    所以千萬不要把設置線程的優先順序當作是線程實際啓動的優先順序哦!
    歡迎你們關注個人公衆號"小猴子的技術筆記",有問題能夠及時和我交流。

相關文章
相關標籤/搜索