Java并发编程实战 06 | 为什么不建议使用线程优先级?
什么是线程优先级?
线程优先级是一个标识,用来提示操作系统或线程调度器哪个线程更重要、更需要优先执行。优先级通常是一个整数值。
在 Java 中,线程优先级的设置范围从 1 到 10,其中 1 是最低优先级,10 是最高优先级。Java 默认情况下,线程的优先级是 5。
优先级高的线程通常会获得更多的 CPU 时间片,从而优先执行。但这不是绝对的,操作系统的线程调度器可能会因为其他因素(如操作系统的负载、线程的状态等)来决定实际的执行顺序。
在 Java 中,我们可以通过 Thread 类的 setPriority() 方法来设置线程的优先级。例如:
public class Demo { public static void main ( String[] args ) { Thread a = new Thread(); System. out .println( "默认线程优先级:" +a.getPriority()); Thread b = new Thread(); b.setPriority( 9 ); System. out .println( "设置线程优先级:" +b.getPriority()); }
}//输出:
默认线程优先级:5
设置线程优先级:9
需要注意的是线程的优先级如果要设置必须在线程启动之前设置好。
父子关系中的线程优先级
如果子线程没有显示设置优先级。那么它会继承父线程的优先级。
class ThreadDemo extends Thread
{public void run(){System.out.println(“Inside run method”);}public static void main(String[] args){// Setting priority for main threadThread.currentThread().setPriority(7);// Printing main thread prioritySystem.out.println("Main thread priority: " + Thread.currentThread().getPriority());// Creating child threadThreadDemo childThread = new ThreadDemo();// Printing child thread prioritySystem.out.println("Child thread priority: " + childThread.getPriority()); //7}
}//输出:
Main thread priority: 7
Child thread priority: 7
注意程序的输出。我们可以看到父线程 ( main ) 和子线程 ( childThread ) 具有相同的优先级。
为什么不推荐手动设置优先级
虽然 Java 提供了从 1 到 10 的线程优先级设置,你可能会认为通过调整线程优先级就能控制线程的执行顺序。然而,实际上并不是这样!
在 Java 中,线程优先级的设置并不总是可靠。线程优先级只是对操作系统的一个“建议”,操作系统不一定会严格按照这些优先级来调度线程的执行顺序。具体的执行顺序还是由操作系统的线程调度算法决定的,这意味着优先级高的线程不一定总是会先执行。
为了验证这一点,我们可以通过代码示例来观察线程优先级对执行顺序的实际影响。以下是一个简单的 Java 代码示例,用于演示线程优先级的效果:
public class TestExecuteOrder {static class MyRunnable implements Runnable {@Overridepublic void run() {System.out.printf("The currently executing thread is:%s,priority:%d%n",Thread.currentThread().getName(),Thread.currentThread().getPriority());}}public static void main(String[] args) {Thread t1 = new Thread(new MyRunnable());t1.setPriority(1);Thread t2 = new Thread(new MyRunnable());t2.setPriority(5);Thread t3 = new Thread(new MyRunnable());t3.setPriority(10);t3.start();t2.start();t1.start();}
}//输出:
The currently executing thread is:Thread-1,priority:5-1,priority:5
The currently executing thread is:Thread-2,priority:10
The currently executing thread is:Thread-0,priority:1
如果线程优先级设置能够完全控制线程的执行顺序,那么我们应该看到优先级为 10 的线程先于优先级为 5 的线程输出结果,而优先级为 1 的线程结果最后输出。
然而,在实际运行中,你可能会发现优先级为 5 的线程却先于优先级为 10 的线程输出结果。这表明线程优先级的设置并没有严格地控制线程的执行顺序,这也反映了线程优先级设置的实际可靠性问题。
在上一篇文章中,我们讨论了线程必须存在于线程组中。那么,当线程的优先级与其线程组的优先级不同时会发生什么?我们用以下代码来验证一下:
public class ThreadGroupOrder {public static void main(String[] args) {ThreadGroup myThreadGroup = new ThreadGroup("myThreadGroup");myThreadGroup.setMaxPriority(6);Thread myThread = new Thread(myThreadGroup, "myThread");myThread.setPriority(8);System.out.println("Thread group priority: " + myThreadGroup.getMaxPriority());System.out.println("Thread priority: " + myThread.getPriority());}
}//输出:
Thread group priority: 6
Thread priority: 6
可以看出如果线程的优先级高于其所在线程组的优先级,那么该线程的优先级将会被线程组的最高优先级替代。也就是说,线程的实际优先级将受到其线程组优先级的限制。