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
主线程执行完毕了,守护线程也要停止了
posted @ 2018-09-02 17:17  IT码客  阅读(225)  评论(0编辑  收藏  举报