一、线程的优先级
在操作系统中,线程可以划分优先级,优先级较高的线程得到的 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多线程编程核心技术》