1.10线程的优先级

在操作系统中,线程是有优先级划分的,优先级较高的线程会得到相对较多的资源。

也就是说CPU会优先执行优先级较高的线程对象中的任务。

设置线程优先级有助于帮“线程规划器”确定下次选择哪一个线程来优先执行。

设置线程的优先级使用setPriority()方法,此方法在JDK的源代码如下:

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

在java中,线程的优先级分为1~10这10个优先级,如果小于1或者大于10,则JDK抛出异常IllegalArgumentException()。

JDK常用下面三个量来预置定义优先级的值。

1.10.1线程优先级的继承特性

在java中线程的优先级具有继承性,比如A线程启动B线程,则B线程的优先级与A是一样的。

线程代码1:

public class Thread1 extends Thread {
    @Override
    public void run() {
        System.out.println("Thread1 run priority = " + this.getPriority());
        Thread2 thread = new Thread2();
        thread.start();
    }
}

线程代码2:

public class Thread2 extends Thread {
    @Override
    public void run() {
        System.out.println("Thread2 run priority = " + this.getPriority());
    }
}

执行代码:

public class Main {
    public static void main(String[] args) {
        System.out.println("Main thread begin priority = " + Thread.currentThread().getPriority());
        //Thread.currentThread().setPriority(6);
        System.out.println("main thread end priority = " + Thread.currentThread().getPriority());
        Thread1 thread1 = new Thread1();
        thread1.start();
    }
}

执行结果(左为有注释,右为没注释):

1.10.2优先级具有规则性:

线程代码1:

public class Thread3 extends Thread {
    @Override
    public void run() {
        long beginTime = System.currentTimeMillis();
        long addResult = 0;
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 50000; j++){
                Random random = new Random();
                random.nextInt();
                addResult = addResult + j;
            }
        }
        long endTime = System.currentTimeMillis();
        System.out.println("thread 3 use time = " + (endTime - beginTime));
    }
}

线程代码2:

public class Thread4 extends Thread {
    @Override
    public void run() {
        long beginTime = System.currentTimeMillis();
        long addResult = 0;
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 50000; j++){
                Random random = new Random();
                random.nextInt();
                addResult = addResult + j;
            }
        }
        long endTime = System.currentTimeMillis();
        System.out.println("thread 4 use time = " + (endTime - beginTime));
    }
}

执行代码:

public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            Thread3 thread3 = new Thread3();
            thread3.setPriority(10);
            thread3.start();
            Thread4 thread4 = new Thread4();
            thread4.setPriority(1);
            thread4.start();
        }
    }
}

执行结果:

跑了多次后,会发现优先的线程会先执行完。

 实际上线程的执行顺序与线程代码的执行顺序无关,与线程的优先级有关,优先级越高越先执行。

1.10.3优先级具有随机性:

随机性意味着优先级高的线程不一定总是能优先执行完。

线程代码1:

public class Thread5 extends Thread {
    @Override
    public void run() {
        long beginTime = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            Random random = new Random();
            random.nextInt();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("thread 5 use time = " + (endTime - beginTime));
    }
}

线程代码2:

public class Thread6 extends Thread {
    @Override
    public void run() {
        long beginTime = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            Random random = new Random();
            random.nextInt();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("thread 6 use time = " + (endTime - beginTime));
    }
}

执行代码:

public class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            Thread5 thread5 = new Thread5();
            thread5.setPriority(5);
            thread5.start();
            Thread6 thread6 = new Thread6();
            thread6.setPriority(6);
            thread6.start();
        }
    }
}

 执行结果:

从这个结果来看线程的优先级具有随机性,不一定优先级高的就一定先执行完。

 1.10.4看谁运行的快:

线程代码1:

public class ThreadA extends Thread {
    private int count = 0;

    public int getCount() {
        return count;
    }

    @Override
    public void run() {
        while (true) {
            count++;
        }
    }
}

线程代码2:

public class ThreadB extends Thread {
    private int count = 0;

    public int getCount() {
        return count;
    }

    @Override
    public void run() {
        while (true) {
            count++;
        }
    }
}

执行线程:

public class Main {
    public static void main(String[] args) {
        try {
            ThreadA a = new ThreadA();
            a.setPriority(Thread.NORM_PRIORITY - 3);
            a.start();
            ThreadB b = new ThreadB();
            b.setPriority(Thread.NORM_PRIORITY + 3);
            b.start();
            Thread.sleep(10000);
            a.stop();
            b.stop();
            System.out.println("a = " + a.getCount());
            System.out.println("b = " + b.getCount());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 执行结果:

优先级高的线程,执行速度更快。

源码地址:https://github.com/lilinzhiyu/threadLearning

本文内容是书中内容兼具自己的个人看法所成。可能在个人看法上会有诸多问题(毕竟知识量有限,导致认知也有限),如果读者觉得有问题请大胆提出,我们可以相互交流、相互学习,欢迎你们的到来,心成意足,等待您的评价。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Create Sun

利用委托与Lambada创建和调用webapi接口

前言   现在项目中用的是webapi,其中有以下问题:       1.接口随着开发的增多逐渐增加相当庞大。     2.接口调用时不好管理。   以上是主要...

3339
来自专栏码匠的流水账

httpclient参数配置

默认的话,是从response里头读timeout参数的,没有读到则设置为-1,这个代表无穷,这样设置是有点问题了,如果是https链接的话,则可能会经常报

541
来自专栏Jackson0714

WCF传输1-你是否使用过压缩或Json序列化?

38510
来自专栏java技术学习之道

分布式之延时任务方案解析

843
来自专栏Linyb极客之路

分布式之延时任务方案解析

对上述的任务,我们给一个专业的名字来形容,那就是延时任务。那么这里就会产生一个问题,这个延时任务和定时任务的区别究竟在哪里呢?一共有如下几点区别

1043
来自专栏架构师小秘圈

为什么分布式一定要有延时任务?

3372
来自专栏web开发

Java SpringMVC 定时任务

1、web.xml ? 2、spring-mvc.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns...

2157
来自专栏张善友的专栏

ASP.NET Web API 接口执行时间监控

软件产品常常会出现这样的情况:产品性能因某些无法预料的瓶颈而受到干扰,导致程序的处理效率降低,性能得不到充分的发挥。如何快速有效地找到软件产品的性能瓶颈,则是我...

2118
来自专栏不会写文章的程序员不是好厨师

[翻译]如何分析Java线程dumps

这是关于故障诊断文章的第二篇,翻译自《How to Analyze Java Thread Dumps》,原文地址:https://dzone.com/arti...

542
来自专栏MelonTeam专栏

RunLoop解读

RunLoop 是ios/osx 应用程序运行的基础,它使我们的程序能够不断处在一个循环中,有效地接受事件并处理事件,可以说,它为整个程序的运行搭建了一个框架...

2227

扫码关注云+社区