JUC源码解读:线程的优先级——为什么优先级较高的线程没有被优先执行?
Java高并发讲解:线程的优先级——为什么优先级较高的线程没有被优先执行?
通常,我们可以使用 “setPriority(int)” 定义线程的优先级,这个范围是1~10, 我们创建线程时,它的默认优先级是5!
在实际开发中,我们是不需要使用这个函数的,但是我们有必要了解它的工作原理
本篇从源码的角度讲解 setPriority()
抛出问题
setPriority()的作用是控制线程的优先级,那么是不是优先级越高的线程就会越优先执行呢?我们创建两个线程观察一下!
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new MyThread("Thread1");
Thread thread2 = new MyThread("Thread2");
thread1.setPriority(1);
thread2.setPriority(10);
thread1.start();
thread2.start();
}
static class MyThread extends Thread{
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
}
}
}
很简单的代码,创建两个线程,控制优先级后让他们打印,我们观察输出,看是不是优先级高的 thread2 最优先执行
Thread1: 0
Thread2: 0
Thread1: 1
Thread1: 2
Thread2: 1
Thread1: 3
Thread1: 4
Thread2: 2
Thread2: 3
Thread2: 4
结果竟然没有优先执行,为什么,难道 setPriority() 方法失效了吗?
别急,我们看看源码
观察源码
我们进入 setPriority() 方法中,可以看到这段简单的代码:
public final void setPriority(int newPriority) {
ThreadGroup g; // 创建线程组
checkAccess(); // 检查是否可用
// 如果定义的优先级不属于1~10这个区间,就报错
if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
throw new IllegalArgumentException();
}
if((g = getThreadGroup()) != null) {
if (newPriority > g.getMaxPriority()) {
newPriority = g.getMaxPriority();
}
// 关键方法
setPriority0(priority = newPriority);
}
}
setPriority0() 是在OS层面上解决线程优先级的问题,可以看到这段代码是没有问题的,那么为什么我们写的程序没有先执行优先级高的呢?
总结答案
在我们的操作系统中,我们的CPU是多核的,因此,我们不知道我们的线程是在哪一个内核里运行的,因此才有了我们的问题
优先级不代表执行顺序,优先级越高,可获得的CPU时间片越长。因此,优先级针对的是可获得CPU时间片的长短问题
我们平常实际开发中,是几乎用不到 setPriority()方法的,因为太复杂了,我们有更好的中间件可以实现线程的资源调度
感谢B站up 河北王校长 的知识分享