并发基础(三)—— java线程优先级小试牛刀

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

转载声明:转载请注明出处,本技术博客是本人原创文章

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 并发基础(三)—— java线程优先级小试牛刀

一、概述

在不同的JVM中(JVM也算是一个操作系统),有着不同的CPU调度算法,对于大部分的JVM来说,优先级也是调度算法中的一个参数。

所以,线程优先级在一定程度上,对线程的调度执行顺序有所影响,但不能用于保证线程的执行顺序,因为优先级仅仅是其中一个参数而已,其他参数还可能有线程的等待时间、执行时间等。而且操作系统也可抗能可以完全不用理会JAVA线程对于优先级的设定。

线程优先级的范围一般是1~10默认是5,但也有的JVM不是这个范围。所以,一般也尽量不要设置优先级为数字,可以使用Thread类的3个静态字段:

static int MAX_PRIORITY : 线程可以具有的最高优先级。 static int MIN_PRIORITY : 线程可以具有的最低优先级。 static int NORM_PRIORITY : 分配给线程的默认优先级。

同时。对于需要较多CPU时间的线程需要设置较低的优先级,这样可以确保处理器不会被独占。

二、实例应用

一直在思考怎么设计,才能用简单明了的例子来证明优先级对线程的执行顺序有影响,最后为了严谨,还是不得不用到线程锁,可能对初学者来说,有点难理解。

不过,思路是很清晰的:就是如何让10个线程一起同时并发。首先让创建的10个线程依次进入对象锁的池中等待,然后当10个线程创建完后,main线程(主线程)同时唤醒这10个线程,于是10个线程同时一起并发竞争CPU,只计算5次,看看线程的结束的先后顺序。(注意:之所以线程的执行次数限制在5次,而不是无限,是因为会发生线程饥饿,高优先级线程占用着CPU,导致低优先级的线程无法被调度!!


public class Test2 {<!-- -->
    //obj对象 用于作为对象锁
    static String obj="";
public static void main(String[] args) {
   //创建十个不同优先级的线程
   for(int i=1;i&lt;10;i++){
       Thread t = new Thread(new Task(),"Thread_"+i);
       t.setPriority(i);
       //线程启动,进入就绪队列
       t.start();
       try {
       //当前线程--main线程 休眠100毫秒,确保线程t已经创建完成,并能运行到等待获取锁处
        Thread.sleep(100);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
   }

   synchronized (obj) {
       //main线程获取对象锁后,唤醒等待在该对象池上的所有线程--就是上面创建的10个线程
       obj.notifyAll();
   }

}
}

  //实现 Runnable接口
  class Task implements Runnable{<!-- -->

    @Override
    public void run() {

        synchronized (Test2.obj) {
            try {
                //在对象Test2.obj上等待,
                Test2.obj.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //线程唤醒后,执行下面的代码
        int count=0;
        //计算5次,不能是while(true),不限制执行次数,否则会发生线程饥饿
        while(count&lt;5){
            count++;
            System.out.println(Thread.currentThread().getName());
            //每次计算完后,让出CPU,重新进入就绪队列,与其他线程一起竞争CPU
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName()+"结束");
    }
  }

测试结果:

  从结果可以看出,虽然线程的结束顺序不是完全按照优先级高低,但也基本是优先级高的线程结束的较快,被CPU调度的概率越大

Thread_9 Thread_5 Thread_6 Thread_8 Thread_7 Thread_9 Thread_8 Thread_7 Thread_9 Thread_8 Thread_9 Thread_7 Thread_9 Thread_7 Thread_8 Thread_9结束 Thread_8 Thread_7 Thread_8结束 Thread_7结束 Thread_4 Thread_5 Thread_6 Thread_3 Thread_5 Thread_6 Thread_5 Thread_6 Thread_5 Thread_6 Thread_5结束 Thread_6结束 Thread_4 Thread_2 Thread_3 Thread_4 Thread_1 Thread_3 Thread_4 Thread_3 Thread_4 Thread_3 Thread_4结束 Thread_3结束 Thread_2 Thread_1 Thread_2 Thread_1 Thread_2 Thread_1 Thread_2 Thread_1 Thread_1结束 Thread_2结束
文章有不当之处,欢迎指正,你也可以关注我的微信公众号: 好好学java,获取优质学习资源。

原文地址:https://sihai.blog.csdn.net/article/details/80255456

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

转载声明:转载请注明出处,本技术博客是本人原创文章

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 并发基础(三)—— java线程优先级小试牛刀


 上一篇
并发基础篇(四)—— java中线程的状态深入浅出 并发基础篇(四)—— java中线程的状态深入浅出
一、线程的五种状态  线程的生命周期可以大致分为5种,但这种说法是比较旧的一种说法,有点过时了,或者更确切的来说,这是操作系统的说法,而不是java的说法。但对下面所说的六种状态的理解有所帮助,所以也写出来,作为参考。 1. NEW: 线
2021-04-04
下一篇 
java并发编程基础系列(五)—— 创建线程的四种方式 java并发编程基础系列(五)—— 创建线程的四种方式
线程的创建一共有四种方式: 继承于 Thread类,重写run()方法;- 实现 Runable接口,实现里面的run()方法;- 使用 FutureTask 实现有返回结果的线程- 使用 ExecutorService、 Execut
2021-04-04