3. 线程的优先级

一、线程的优先级

在操作系统中,线程可以划分优先级,优先级较高的线程得到的 CPU 资源较多,即 CPU 优先执行优先级较高的线程对象的任务

在 Java 中使用 setPriority 方法来设置优先级,同时把优先级划分成 1~10 这10个等级,如果小于 1 或者大于 10,则 JDK 会抛出异常

// 线程最小的优先级等级
public final static int MIN_PRIORITY = 1;

// 线程默认的优先级等级
public final static int NORM_PRIORITY = 5;

// 线程最大的优先级等级
public final static int MAX_PRIORITY = 10;

public final void setPriority(int newPriority) {
    ThreadGroup g;
    checkAccess();
    // 如果线程优先级等级大于 10 或者小于 1,则会抛出异常
    if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
        throw new IllegalArgumentException();
    }
    if((g = getThreadGroup()) != null) {
        if (newPriority > g.getMaxPriority()) {
            newPriority = g.getMaxPriority();
        }
        // 该方法是Java的本地方法
        setPriority0(priority = newPriority);
    }
}

二、线程优先级的继承特性

线程的优先级具有继承性,比如 A 线程启动 B 线程,那么 B 线程的优先级和 A 线程是一样的

看个例子:

class MyThread0_1 extends Thread {
    @Override
    public void run() {
        //因为线程 Thread1 是由线程 Thread0 调用,因此 Threa1 的优先级和 Thread0 一样,都是 8
        System.out.println("MyThread0_1 run priority = " + this.getPriority());
    }
}

/**
 * 线程的优先级具有继承性,比如 A 线程启动 B 线程,那么 B 线程的优先级和 A 线程是一样的
 */
public class MyThread extends Thread {

    @Override
    public void run() {
        //因为线程 Thread0 是由线程 main 调用的,因此 Thread0 的优先级和 main 的优先级一样,都是 6
        System.out.println("MyThread0 run priority = " + this.getPriority());
        //创建线程 MyThread0_1
        MyThread0_1 myThread0_1 = new MyThread0_1();
        //为线程 MyThread0_1 设置优先级为 8
        myThread0_1.setPriority(8);
        //在线程 Thread-0 里面启动线程 MyThread0_1
        myThread0_1.start();
    }

    public static void main(String[] args) {
        System.out.println("main thread begin priority = " +
                Thread.currentThread().getPriority());
        //为线程 main 设置优先级为 6
        Thread.currentThread().setPriority(6);
        System.out.println("main thread end priority = " +
                Thread.currentThread().getPriority());
        //创建线程 Thread-0
        MyThread thread = new MyThread();
        //在线程 main 里面启动线程 Thread0
        thread.start();
    }

}

结果是:

main thread begin priority = 5
main thread end priority = 6
MyThread0 run priority = 6
MyThread0_1 run priority = 8

三、优先级的规则性

直接看个例子

// 线程 MyThread_1
class MyThread1_1 extends Thread {
    @Override
    public void run() {
        long beginTime = System.currentTimeMillis();
        long addResult = 0;
        for (int i = 0; i < 5000; i++) {
            Random random = new Random();
            random.nextInt();
            addResult = addResult + 1;
        }
        long endTime = System.currentTimeMillis();
        System.out.println("thread 1_1 use time = " + (endTime - beginTime));
    }
}

// 线程 MyThread1
public class MyThread1 extends Thread {
    @Override
    public void run() {
        long beginTime = System.currentTimeMillis();
        long addResult = 0;
        for (int i = 0; i < 5000; i++) {
            Random random = new Random();
            random.nextInt();
            addResult = addResult + 1;
        }
        long endTime = System.currentTimeMillis();
        System.out.println("thread 1 use time = " + (endTime - beginTime));
    }

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            //创建线程 Thread1
            MyThread1 thread1 = new MyThread1();
            //为线程 Thread1 设置优先级为 10
            thread1.setPriority(10);
            thread1.start();
            
            //创建线程 Thread1_1
            MyThread1_1 thread1_1 = new MyThread1_1();
            //为线程 Thread1_1 设置优先级 2
            thread1_1.setPriority(2);
            thread1_1.start();
        }
    }
}

结果:

//第 1 次执行
thread 1 use time = 1
thread 1 use time = 2
thread 1 use time = 8
thread 1 use time = 8
thread 1 use time = 8
thread 1_1 use time = 1
thread 1_1 use time = 2
thread 1_1 use time = 1
thread 1_1 use time = 4
thread 1_1 use time = 1

//第 2 次执行
thread 1 use time = 4
thread 1_1 use time = 3
thread 1 use time = 10
thread 1 use time = 9
thread 1 use time = 10
thread 1 use time = 10
thread 1_1 use time = 5
thread 1_1 use time = 10
thread 1_1 use time = 1
thread 1_1 use time = 0

//第 3 次执行
thread 1 use time = 5
thread 1_1 use time = 5
thread 1_1 use time = 5
thread 1_1 use time = 7
thread 1 use time = 8
thread 1 use time = 9
thread 1 use time = 8
thread 1 use time = 9
thread 1_1 use time = 9
thread 1_1 use time = 11

可以看到,大部分情况下,高优先级的线程 thread 1 总是大部分先执行完,但不代表它全部先执行完,除了第1次执行,第2、3次执行都有线程 thread 1_1 比线程 thread 1 还要先执行完的情况

不要把线程的优先级和运行结果的顺序作为衡量的标志,优先级高的线程并不一定每次都先执行完 run 方法中的任务,即 线程的优先级和打印顺序无关,不要将这两者相关联

同时,线程的优先级也和代码的执行顺序无关

四、线程运行的速度

优先级高的线程运行的速度更快

看例子:

class ThreadB extends Thread {
    private int count = 0;

    public int getCount() {
        return count;
    }

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

public class ThreadA extends Thread {

    private int count = 0;

    public int getCount() {
        return count;
    }

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

    public static void main(String[] args) throws InterruptedException {
        ThreadA threadA = new ThreadA();
        threadA.setPriority(Thread.NORM_PRIORITY - 3);
        threadA.start();

        ThreadB threadB = new ThreadB();
        threadB.setPriority(Thread.NORM_PRIORITY + 3);
        threadB.start();
		// 使 main 线程让出CPU 2秒的时间来执行线程A和B
        Thread.sleep(2000);
        threadA.stop();
        threadB.stop();

        System.out.println("a = " + threadA.getCount());
        System.out.println("b = " + threadB.getCount());
    }
}

结果是:

线程 a 优先级是 2,运行速度为:919673973
线程 b 优先级是 8,运行速度为:1129959772

五、参考

《Java多线程编程核心技术》

猜你喜欢

转载自blog.csdn.net/babycan5/article/details/83246748