Java多线程 - 线程优先级

时间:2013-12-02 16:34:09

标签: 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...");
    }
}

在上述程序中,即使我改变了优先级,我也发现输出没有区别。 另外,如何使用线程优先级的实时应用将会有很大帮助。 感谢。

6 个答案:

答案 0 :(得分:11)

线程优先级只是OS任务调度程序的提示,并且依赖于底层操作系统。操作系统将尝试为高优先级线程分配更多资源,但不保证。因此,如果您的程序依赖于线程优先级而不是将程序绑定到底层操作系统,这很糟糕。

来自 Java Concurrency in Practice

  

避免使用线程优先级的诱惑,因为它们会增加   平台依赖,可能导致生活问题。大多数并发   应用程序可以使用所有线程的默认优先级。

答案 1 :(得分:5)

线程优先级只是OS任务调度程序的提示。任务调度程序只会尝试将更多资源分配给具有更高优先级的线程,但是没有明确的保证。

实际上,它不仅与Java或JVM相关。大多数非实时操作系统仅以建议的方式使用线程优先级(托管或非托管)。

同样非常重要的是,Priorties与每个底层平台都不同。因此,你有点松散你的平台java自由。请参阅此摘要:

实际上,某些优先级可以映射到相同的&#34; native&#34;优先级。这是列表(基于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,因为你无论如何都不能依赖它。 (当然有一些场景是有意义的)

答案 2 :(得分:1)

在某些情况下,为线程设置优先级很有用,您不能一如既往地开始相信来自此类设置的任何保证:线程的执行顺序未定义 。如果你认为如果你给它一个更高的优先级,你的线程会提前完成,请再次阅读上面的陈述,直到你的想法。 ;)

您应该根据此线程与其他线程相比获得执行时间的重要性来定义优先级。即使底层系统没有任何保证,它仍然可以为那些支持它的JVM提供好处。

示例:您有一个程序根据JFrame中的用户输入执行一些繁重的计算。将这些后台线程设置为低优先级是一个好习惯,因为JFrame响应比计算更重要(这需要很长时间才能完成,再多几毫秒不会受到伤害) 。操作系统仍会将大部分CPU时间分配给低优先级线程,除非更重要需要它。但是,这些更重要的东西是优先考虑的事情是好的。

现在可能会发生在某些系统上忽略优先级设置并且JFrame再次无响应,但是这对您的代码没有任何影响,因此首先不会将优先级设置为低。

答案 3 :(得分:1)

任务的大小太小,可能会在开始后立即完成。此外,如果您有足够的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

答案 4 :(得分:0)

希望有帮助!

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
}

答案 5 :(得分:-1)

 //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;
}
相关问题