簡體   English   中英

Java多線程 - 線程優先級

[英]Java multithreading - thread priority

任何人都可以解釋線程優先級如何在java中工作。 這里的混淆是,如果java根據其優先級不保證Thread的實現,那么為什么這個setpriority()函數用於。

我的代碼如下:

public class ThreadSynchronization implements Runnable{

    public synchronized void run() {
        System.out.println("Starting Implementation of Thread "+Thread.currentThread().getName());
        for(int i=0;i<10;i++)
        {
            System.out.println("Thread "+Thread.currentThread().getName()+" value : "+i);
        }
        System.out.println("Ending Implementation of Thread "+Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        System.out.println("Program starts...");
        ThreadSynchronization th1 = new ThreadSynchronization();
        Thread t1 = new Thread(th1);
        t1.setPriority(1);
        synchronized(t1)
        {
            t1.start();
        }

        ThreadSynchronization th2 = new ThreadSynchronization();
        Thread t2 = new Thread(th2);
        t2.setPriority(9);
        synchronized (t2) {
            t2.start(); 
        }

        System.out.println("Program ends...");
    }
}

在上面的程序中,即使我改變優先級,我發現輸出沒有區別。 另外,如何使用線程優先級的實時應用將會有很大幫助。 謝謝。

線程優先級只是OS任務調度程序的提示,並且依賴於底層操作系統。 操作系統將嘗試為高優先級線程分配更多資源,但不保證。 因此,如果您的程序依賴於線程優先級而不是將程序綁定到底層操作系統,這很糟糕。

來自Java Concurrency in Practice

避免使用線程優先級的誘惑,因為它們會增加平台依賴性並導致活動問題。 大多數並發應用程序可以使用所有線程的默認優先級。

線程優先級只是OS任務調度程序的提示。 任務調度程序只會嘗試將更多資源分配給具有更高優先級的線程,但是沒有明確的保證。

實際上,它不僅與Java或JVM相關。 大多數非實時操作系統僅以建議的方式使用線程優先級(托管或非托管)。

同樣非常重要的是,Priorties與每個底層平台都不同。 因此,你有點松散你的平台java自由。 請參閱此摘要:

實際上,某些優先級可以映射到相同的“本機”優先級。 這是列表(基於OpenJDK 6中的熱點代碼):

的Solaris
1⇒0
2⇒32
3⇒64
4⇒96
5 - 10⇒127
值得注意的是,在Solaris上,您不能將線程優先級提高到正常范圍以上,只能降低它:5的優先級值與任何更高的值相同。

Linux的
1 - 10⇒4 - -5(漂亮的值)值得注意的是,在Linux上,Java中的不同線程優先級確實映射到本機級別的不同優先級值。

視窗
1 - 2⇒THREAD_PRIORITY_LOWEST
3 - 4⇒THREAD_PRIORITY_BELOW_NORMAL
5 - 6⇒THREAD_PRIORITY_NORMAL
7 - 8⇒THREAD_PRIORITY_ABOVE_NORMAL
9 - 10⇒THREAD_PRIORITY_HIGHEST

我已經開發了很多多線程java應用程序,在我看來,如果你必須設置優先級,你還有另一個問題。 就像一個耗費大量CPU時間等的糟糕的algorythm ....我總是建議不要改變java線程prio,因為你無論如何都不能依賴它。 (當然有一些場景有意義)

在某些情況下,為線程設置優先級很有用,您不能一如既往地開始相信來自此類設置的任何保證: 使用線程執行的順序是不確定的 如果你認為如果你給它一個更高的優先級,你的線程會提前完成,請再次閱讀上面的陳述,直到你的想法。 ;)

您應該根據此線程與其他線程相比獲得執行時間的重要性來定義優先級。 即使底層系統沒有任何保證,它仍然可以為那些支持它的JVM提供好處。

示例:您有一個程序根據JFrame中的用戶輸入執行一些繁重的計算。 將這些后台線程設置為低優先級是一個好習慣,因為JFrame響應比計算更重要(這需要很長時間才能完成,再多幾毫秒不會受到傷害) 。 操作系統仍會將大部分CPU時間分配給低優先級線程,除非有更重要的需要。 但是,這些更重要的東西得到優先考慮是件好事。

現在可能會發生在某些系統上忽略優先級設置並且JFrame再次無響應,但是這對您的代碼沒有任何影響,因此首先不將優先級設置為低。

任務的大小太小,可能會在開始后立即完成。 此外,如果您有足夠的CPU核心,每個工作線程將分配給一個核心,因此結果將是相同的。

在不同的上下文中嘗試實驗,首先增加任務大小(例如通過循環一千次到一百萬次,無需打印)然后增加線程數以超過你擁有的內核數量,第三次創建線程並且然后啟動所有線程(你不能一次啟動它們,你仍然需要循環它們)。

就我而言,我選擇了10個線程,因為我在具有兩個超線程內核的處理器上運行代碼,運行四個同時線程。

我對你的例子的改動:

public class ThreadPriority implements Runnable {

    public synchronized void run() {
        System.out.println("Starting Implementation of Thread " + Thread.currentThread().getName());
        float s = 0;
        for (int i = 0; i < 1000; i++)
            for (int k = 0; k < 1000000; k++)
                s += k;
        System.out.println("Ending Implementation of Thread " + Thread.currentThread().getName() + " " + s);
    }

    Thread t;

    public ThreadPriority(String name, int prio) {
        t = new Thread(this);
        t.setName(name);
        t.setPriority(prio);
    }

    public void start() {
        synchronized (t) {
            t.start();
        }
    }

    public static void main(String[] args) {
        System.out.println("Program starts...");
        ThreadPriority[] th = new ThreadPriority[10];
        for (int i = 0; i < th.length; i++) {
            th[i] = new ThreadPriority("T" + i, i / 2 + 1);
        }

        for (ThreadPriority tp : th)
            tp.start();

        System.out.println("Program ending, wait for all the threads to complete");
    }
}

結果是:

Program starts...
Starting Implementation of Thread T0
Starting Implementation of Thread T9
Starting Implementation of Thread T8
Starting Implementation of Thread T5
Program ending, wait for all the threads to complete
Starting Implementation of Thread T4
Starting Implementation of Thread T6
Starting Implementation of Thread T7
Starting Implementation of Thread T2
Starting Implementation of Thread T3
Starting Implementation of Thread T1
Ending Implementation of Thread T6 1.7592186E13
Ending Implementation of Thread T7 1.7592186E13
Ending Implementation of Thread T4 1.7592186E13
Ending Implementation of Thread T8 1.7592186E13
Ending Implementation of Thread T9 1.7592186E13
Ending Implementation of Thread T5 1.7592186E13
Ending Implementation of Thread T2 1.7592186E13
Ending Implementation of Thread T0 1.7592186E13
Ending Implementation of Thread T1 1.7592186E13
Ending Implementation of Thread T3 1.7592186E13

正如您所看到的,低數字線程往往會在稍后結束,因為高數字線程具有更高的優先級。 通過將比例上下顛倒:

    for (int i = 0; i < th.length; i++) {
        th[i] = new ThreadPriority("T" + i, 9 - i / 2 );
    }

低數字線程比高線程完成得更快。 有些線程甚至在其他線程啟動之前就已完成,因為它們與調用程序相比具有更高的優先級:

Program starts...
Starting Implementation of Thread T0
Starting Implementation of Thread T1
Starting Implementation of Thread T2
Starting Implementation of Thread T3
Program ending, wait for all the threads to complete
Ending Implementation of Thread T2 1.7592186E13
Ending Implementation of Thread T3 1.7592186E13
Ending Implementation of Thread T0 1.7592186E13
Ending Implementation of Thread T1 1.7592186E13
Starting Implementation of Thread T9
Starting Implementation of Thread T4
Starting Implementation of Thread T8
Starting Implementation of Thread T7
Starting Implementation of Thread T5
Starting Implementation of Thread T6
Ending Implementation of Thread T4 1.7592186E13
Ending Implementation of Thread T5 1.7592186E13
Ending Implementation of Thread T7 1.7592186E13
Ending Implementation of Thread T8 1.7592186E13
Ending Implementation of Thread T9 1.7592186E13
Ending Implementation of Thread T6 1.7592186E13

希望能幫助到你!

package priority;

public class ThreadPriorityApp {

    // Note : Thread priority may not be supported in some OS due to underlying task scheduler at OS level

    /**
     * MyThread is an inner class implementing Thread functionality
     *
     */
    class MyThread extends Thread {

        public MyThread(String threadName) {
            super(threadName);
        }
        public void run() {
            System.out.println("Running  thread - " + Thread.currentThread().getName());
        }
    }

    public static void main(String[] args) {

        //If priority is not set then main priority is set to threads created inside main thread - Parent to child
        // Main thread priority - 5, is set to Thread 1 and Thread 2, if not manually assigned (commenting Line #34 and #35)
        System.out.println("Main thread priority - " + Thread.currentThread().getPriority());

        ThreadPriorityApp threadPriorityApp = new ThreadPriorityApp();

        //We are creating two threads
        MyThread th = threadPriorityApp.new MyThread("Thread 1");
        MyThread th2 = threadPriorityApp.new MyThread("Thread 2");

        // Range 1 to 10 - 10 being given as MAX Priority
        th.setPriority(Thread.MIN_PRIORITY);
        th2.setPriority(Thread.MAX_PRIORITY);

        //We have started Thread 1 first and then Thread 2 later
        th.start();
        th2.start();

//      Possible Outcomes(1) (With Priority - Line #34 and #35) :
//      Running  thread - Thread 2
//      Running  thread - Thread 1


//      Possible Outputs(2) : (Without Priority - commenting Line #34 and #35)
//      (1) Running  thread - Thread 1
//          Running  thread - Thread 2
//      OR
//      (2) Running  thread - Thread 2
//          Running  thread - Thread 1

    }

    //Happy coding -- Parthasarathy S
}
 //The iterative and recursive with memorize both shows count as 1424 for digits of length ten starting with 1.
 int[][] b = {{4,6},{6,8},{7,9},{4,8},{0,3,9},{},{1,7,0},{2,6},{1,3},{2,4}};
 public int countIterative(int digit, int length) {
    int[][] matrix = new int[length][10];
    for(int dig =0; dig <=9; dig++){
          matrix[0][dig] = 1;
    }
    for(int len = 1; len < length; len++){
        for(int dig =0; dig <=9; dig++){
          int sum = 0;
          for(int i : b[dig]){
            sum += matrix[len-1][i];
          }
          matrix[len][dig] = sum;
        }
    }
    return matrix[length-1][digit];
}
public int count(int index, int length, int[][] matrix ){
    int sum = 0;
    if(matrix[length-1][index] > 0){
       return matrix[length-1][index];
    }
    if( length == 1){
        return 1;
    }
    for(int i: b[index] )  {
         sum += count(i, length-1,matrix);
    }
    matrix[length-1][index] = sum;
    return sum;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM