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 河北王校长 的知识分享

posted @ 2024-03-11 18:31  yangruomao  阅读(16)  评论(0编辑  收藏  举报