为了账号安全,请及时绑定邮箱和手机立即绑定

Java 多线程(二)之 Thread 优先级

标签:
Java

Thread 中线程优先级相关属性

每个线程均有优先级,在 Thread 中, 与优先级对应的属性如下:

/**
 * 线程的优先级属性
 */private int priority;/**
 * 线程所能拥有的最大优先级.
 */public final static int MIN_PRIORITY = 1;/**
 * 线程默认的优先级.
 */public final static int NORM_PRIORITY = 5;/**
 * 线程所能拥有的最大优先级.
 */public final static int MAX_PRIORITY = 10;

相关函数

在此只讨论 Thread 类中的。

优先级初始化

 private void init(ThreadGroup g, Runnable target, String name,                      long stackSize, AccessControlContext acc) {    // ....
    this.priority = parent.getPriority();
    setPriority(priority);   // ....}

init() 函数对优先级进行了初始化。并调用 setPriority(priority) 函数进行设置。从中得知, 线程的优先级是继承于创建它的线程的。

设置优先级

在 init() 中, 除了给 this.priority 赋值, 还调用了 setPriority(priority) 函数, 因为在该函数内部还调用了一个 native 方法。

public final void setPriority(int newPriority) {
    ThreadGroup g;
    checkAccess();    // 不能大于最大优先级 MAX_PRIORITY
    if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {        throw new IllegalArgumentException();
    }    if((g = getThreadGroup()) != null) {        // 如比所属线程组的最大优先级还大, 则取线程组的最大优先级
        if (newPriority > g.getMaxPriority()) {
            newPriority = g.getMaxPriority();
        }
        setPriority0(priority = newPriority);
    }
}

由代码可知, 设置的优先级不能大于最大优先级,也不能大于所在线程组的最高优先级

获取优先级

获取当前的优先级, 其实就是返回 priority 属性的值。

public final int getPriority() {    return priority;
}

从以上可知, 在 Thread 中, 线程的优先级有如下特点:

  1. Java 线程的优先级从 1~10;

  2. Java 线程默认优先级是 5;

  3. Java 线程的优先级继承于创建它的线程。

是不是感觉 2 和 3 有所矛盾呢?可以在后面的代码和结果中找答案。

默认优先级

先上代码来感受一下线程优先级的作用:

public class ThreadPriorityTest {    class PrimeRun implements Runnable {        public void run() {
            System.out.println(Thread.currentThread().getName() +"::"+
                    Thread.currentThread().getPriority());
            System.out.println(Thread.currentThread().getName() + " Run begin");            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName()+"::"+i);
            }
            System.out.println(Thread.currentThread().getName() + " Run end");
        }
    }    public void test(){
        System.out.println(Thread.currentThread().getName()+" begin");
        Thread p4 = new Thread(new PrimeRun());
        Thread p6 = new Thread(new PrimeRun());
        p4.setName("P4");
        p6.setName("P6");
        p4.start();
        p6.start();
        System.out.println(Thread.currentThread().getName()+" end");
    }    public static void main(String[] args) {        new ThreadPriorityTest().test();
    }
}

在 PrimeRun 类的 run() 方法中, 只是对 0 到 10 进行输出, 前面加上线程名字以识别。没有对线程进行设置, 按以上分析的 init() 方法可知, 优先级继承于 ThreadPriorityTest 中的优先级, 没进行设置优先级默认为 5。 输出如下:

https://img1.sycdn.imooc.com//5b8ba5290001010d03410531.jpg

可以看到 p4 和 p6 的线程优先级都是 5, 输出是无序的, P4 和 P6 交叉输出, 因此每次的结果都不一样。

指定优先级

将线程中的优先级改一下, test() 函数变成如下:

public void test(){
    System.out.println(Thread.currentThread().getName()+" begin");
    Thread p4 = new Thread(new PrimeRun());
    Thread p6 = new Thread(new PrimeRun());
    p4.setName("P4");
    p4.setPriority(4);
    p6.setName("P6");
    p6.setPriority(6);
    p4.start();
    p6.start();
    System.out.println(Thread.currentThread().getName()+" end");
}

在运行之后的输出如下:

https://img1.sycdn.imooc.com//5b8ba5310001b4e902260493.jpg

可以看到, P6 先于 P4 运行完。

注意事项

但是(一般 「但是」 后面的东西都要注意)

优先级和操作系统及虚拟机版本相关。
++优先级只是代表告知了 「线程调度器」该线程的重要度有多大。如果有大量线程都被堵塞,都在等候运
行,调试程序会首先运行具有最高优先级的那个线程。然而,这并不表示优先级较低的线程不会运行(换言之,不会因为存在优先级而导致死锁)。若线程的优先级较低,只不过表示它被准许运行的机会小一些而已。++

因此, 在实际的编码时, 认为高优先级一定先于低优先级的线程执行, 最后会出问题的。

优先级继承

而关于特点 2 和 3 的区别, 我们在第一次 test() 时, P4 和 P6 的优先级都是 5, 我们将函数改一下:

 public void test(){
    Thread.currentThread().setPriority(10);
    System.out.println(Thread.currentThread().getName()+" begin");
    Thread p4 = new Thread(new PrimeRun());
    Thread p6 = new Thread(new PrimeRun());
    p4.setName("P4");
    p6.setName("P6");
    p4.start();
    p6.start();
    System.out.println(Thread.currentThread().getName()+" end");
}

在创建 P4 和 P6 之前将当前线程的优先级设置为 10, 并在 run() 中去掉一些无关的输出, 最后输入如下:

https://img1.sycdn.imooc.com//5b8ba5380001005602100154.jpg

原文出处:https://www.cnblogs.com/homejim/p/9527226.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消