关于java:Java线程设置了优先级就一定生效吗Java线程的priority源码解析

    欢送大家关注我的公众号“小猴子的技术笔记”,有问题能够及时和我交换。
    咱们晓得在构建一个线程对象的时候能够给线程设置一个优先级,就像上面这样:

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("设置线程的优先级");
    }
}
public class MyRunnableTest {
    public static void main(String[] args) {
        Thread thread = new Thread(new MyRunnable());
        thread.setPriority(10);
        thread.start();
    }
}

    或者你已经有过这样的想法,如果有多个线程的话,是不是能够依照这种优先级设置的程序来启动线程呢?咱们来看上面这个例子:

public class MinPriority implements Runnable {
    @Override
    public void run() {
        System.out.println("线程的优先级为1");
    }
}
public class NormalPriority implements Runnable {
    @Override
    public void run() {
        System.out.println("线程的优先级为5");
    }
}
public class MaxPriority implements Runnable {
    @Override
    public void run() {
        System.out.println("线程的优先级为10");
    }
}
public class ThreadPriorityTest {
    public static void main(String[] args) {
        Thread minThread = new Thread(new MinPriority());
        minThread.setPriority(1);
        Thread maxThread = new Thread(new MaxPriority());
        maxThread.setPriority(10);
        Thread normalThread = new Thread(new NormalPriority());
        normalThread.setPriority(5);
        minThread.start();
        maxThread.start();
        normalThread.start();
    }
}

    我模仿了三个不同优先级别的线程,在构建实现之后“同时”启动,而后察看后果。也请你尝试把这些代码拷贝到你的开发工具中,而后尝试运行“ThreadPriorityTest”,兴许第一次你看到的后果是这样的:

线程的优先级为10
线程的优先级为5
线程的优先级为1

    你会很开心,因为它依照你的预期来输入了。然而,请尝试多运行几次“ThreadPriorityTest”你兴许会发现有其余的不同的后果:

线程的优先级为5
线程的优先级为10
线程的优先级为1

    看到下面后果之后,回过头来看咱们最后设置的线程的优先级貌似并没有起到什么作用。这到底是为什么呢?别着急!咱们先来过一遍设置线程优先级的源码:

public final void setPriority(int newPriority) {
    ThreadGroup g;
    checkAccess();
    if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
        throw new IllegalArgumentException();
    }
    if((g = getThreadGroup()) != null) {
        if (newPriority > g.getMaxPriority()) {
            newPriority = g.getMaxPriority();
        }
        setPriority0(priority = newPriority);
    }
}

    首先申明了一个线程组对象,而后“checkAccess()”进行了安全检查,紧接着就是判断咱们传递过去的优先级的值,判断它是不是低于最小的优先级,高于最大的优先级,如果满足上述条件的话,就间接抛出参数不非法的异样。
线程Thread类提供了三个优先级的常量:

// 可设置最小优先级
public final static int MIN_PRIORITY = 1;
// 默认的优先级,如果没设置的话,默认为此值
public final static int NORM_PRIORITY = 5;
// 可设置最大优先级
public final static int MAX_PRIORITY = 10;

    源码中比拟重要的就是“((g = getThreadGroup()) != null)”的判断,第一步先通过“getThreadGroup()”办法获取到以后的线程组赋值给“g”。获取线程组“getThreadGroup()”办法的源码如下:


public final ThreadGroup getThreadGroup() {
    return group;
}

    拿到返回的线程组之后判断咱们显示设置的线程优先级的值是否大于了线程组的优先级,如果大于了,就设置为线程组的优先级。

    最初就是通过“setPriority0(priority = newPriority)”办法给线程赋值:

private native void setPriority0(int newPriority);

    能够看到最初设置线程的这个办法是调用的本地办法,那么就是交由底层去实现的。

    其实线程的优先级设置能够了解为线程抢占CPU工夫片的概率,尽管概率比拟大,然而它不肯定就是依照优先级的程序去抢占CPU工夫片的,具体的执行程序还是要依据谁先抢到了CPU的工夫片,谁就先来执行。

    因而千万不要把设置线程的优先程序当做是线程理论启动的优先程序哦!
    欢送大家关注我的公众号“小猴子的技术笔记”,有问题能够及时和我交换。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理