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();
    }
}

    或许你曾经有过这样的想法,若是有多个线程的话,是否是能够按照这种优先级设置的顺序来启动线程呢?咱们来看下面这个例子:ide

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类提供了三个优先级的常量:code

// 可设置最小优先级
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()”方法的源码以下:orm

public final ThreadGroup getThreadGroup() {
    return group;
}

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

    最后就是经过“setPriority0(priority = newPriority)”方法给线程赋值:开发

private native void setPriority0(int newPriority);

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

    其实线程的优先级设置能够理解为线程抢占CPU时间片的几率,虽然几率比较大,可是它不必定就是按照优先级的顺序去抢占CPU时间片的,具体的执行顺序仍是要根据谁先抢到了CPU的时间片,谁就先来执行。

    所以千万不要把设置线程的优先顺序当作是线程实际启动的优先顺序哦!
    欢迎你们关注个人公众号"小猴子的技术笔记",有问题能够及时和我交流。

相关文章
相关标签/搜索