Javamultithreading – 线程优先级

任何人都可以解释线程优先级如何在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

我已经开发了很多multithreadingjava应用程序,在我看来,如果你必须设置优先级,你还有另一个问题。 就像一个消耗大量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 
  //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; }