• Java线程优先级及守护线程(二)


    简述

    在操作系统中,线程是可以划分优先级的,优先级较高的线程,得到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就会抛出异常 throw new IllegalArgumentException()。在jdk中使用3个常量来预定义优先级的值:

     /**
         * 线程最小优先级
         */
        public final static int MIN_PRIORITY = 1;
    
       /**
         * 线程默认优先级
         */
        public final static int NORM_PRIORITY = 5;
    
        /**
         * 线程最大优先级
         */
        public final static int MAX_PRIORITY = 10;

    线程优先级具有3中特性,分别是:继承性、规则性、随机性,下面将一一说明:

    1、继承性

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

    public class ThreadA extends Thread {
        @Override
        public void run() {
            System.out.println(" ThreadA run priority=" + this.getPriority());
            ThreadB thread2 = new ThreadB();
            thread2.start();
        }
    }
    
    public class ThreadB extends Thread {
        @Override
        public void run() {
            System.out.println(" ThreadB run priority=" + this.getPriority());
        }
    }
    
    public class ThreadDemo {
        public static void main(String[] args) {
            Thread.currentThread().setPriority(6);
            System.out.println(" main thread priority=" + Thread.currentThread().getPriority());
    
            ThreadA threadA = new ThreadA();
            threadA.start();
        }
    }
    

    输出结果:

     main thread priority=6
     ThreadA run priority=6
     ThreadB run priority=6

    从结果可以看出,ThreadA继承了main的优先级,ThreadB继承了ThreadA的优先级

    2、规则性

    public class ThreadA extends Thread {
        @Override
        public void run() {
            long beginTime = System.currentTimeMillis();
            long aCount = 0;
            for (int i = 0; i < 50000; i++) {
                Random random = new Random();
                aCount += random.nextInt() + i;
            }
            long endTime = System.currentTimeMillis();
            System.out.println(" ★ ★ ★ ★ ★ thread A use time=" + (endTime - beginTime));
        }
    }
    
    public class ThreadB extends Thread {
        @Override
        public void run() {
            long beginTime = System.currentTimeMillis();
            long bCount = 0;
            for (int i = 0; i < 50000; i++) {
                Random random=new Random();
                bCount+=random.nextInt()+i;
            }
            long endTime = System.currentTimeMillis();
            System.out.println(" ☆ ☆ ☆ ☆ ☆ thread B use time=" + (endTime - beginTime));
        }
    }
    
    
    public static void main(String[] args) {
            for (int i = 0; i < 5; i++) {
                ThreadA threadA = new ThreadA();
                threadA.setPriority(10);
                threadA.start();
    
                ThreadB threadB = new ThreadB();
                threadB.setPriority(6);
                threadB.start();
            }
        }

    输出结果:

    ★ ★ ★ ★ ★ thread A use time=23
     ☆ ☆ ☆ ☆ ☆ thread B use time=29
     ★ ★ ★ ★ ★ thread A use time=29
     ☆ ☆ ☆ ☆ ☆ thread B use time=34
     ★ ★ ★ ★ ★ thread A use time=34
     ★ ★ ★ ★ ★ thread A use time=36
     ☆ ☆ ☆ ☆ ☆ thread B use time=38
     ☆ ☆ ☆ ☆ ☆ thread B use time=37
     ★ ★ ★ ★ ★ thread A use time=7
     ☆ ☆ ☆ ☆ ☆ thread B use time=4

    运行多次之后,我们发现高优先级的线程总是大部分先执 完,但不代表高优先级的 线程全部先执行完。说明线程的优先级具有一定的规则性,也就是CPU尽量将执行资源 让给优先级比较高的线程。

    3、随机性

    前面的事例证明了线程的优先级较高则优先执行完 run()方法中的任务, 但这个结果不是肯定的, 因为线程的优先级还具有随机性,也就是线程优先级高的线程并不一定每次都先执行完
    。将上述事例两个线程的优先级分别调整为相近的优先级,运行多次后就会发现这种随机性。

    什么是守护线程

    在Java线程中有两种类型的线程,一种是用户线程,另一种是守护线程。

    守护线程是一种特殊的线程,典型的守护线程就是垃圾回收线程,当进程中没有用户线程了,则垃圾回收线程也就没有存在的必要了,会自动销毁。

    public class MyThread extends Thread {
        private int i = 0;
    
        @Override
        public void run() {
            try {
                while (true) {
                    i++;
                    System.out.println(" i=" + (i));
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public class ThreadDemo {
        public static void main(String[] args) {
            try {
                MyThread thread = new MyThread();
                thread.setDaemon(true);
                thread.start();
                Thread.sleep(5000);
                System.out.println("主线程执行完毕了,守护线程也要停止了");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    输出结果:

     i=1
     i=2
     i=3
     i=4
     i=5
    主线程执行完毕了,守护线程也要停止了
  • 相关阅读:
    AcWing每日一题--数字三角形
    AcWing每日一题--货仓选址
    Codeforces Round #693
    动态规划--多重背包
    动态规划--完全背包
    动态规划--01背包
    博弈论--SG函数
    博弈论--Nim游戏
    基础数论--容斥定理
    基础数论--卡特兰数
  • 原文地址:https://www.cnblogs.com/liukaifeng/p/10052600.html
Copyright © 2020-2023  润新知