线程的优先级是可以被定义的,通过源码我们能够看到:
public final void setPriority(int newPriority) {
ThreadGroup g;
checkAccess();
// 如果设置的 priority 大于系统设置的最大值,或者小于系统设置的最小值
// 抛出异常
if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
throw new IllegalArgumentException();
}
if((g = getThreadGroup()) != null) {
// 如果设置线程的优先级大于线程组的优先级,则重置线程的优先级为线程组的优先级
if (newPriority > g.getMaxPriority()) {
newPriority = g.getMaxPriority();
}
setPriority0(priority = newPriority);
}
}
一个 Thread 必然存在于一个 ThreadGroup , Thread 有自己的优先级, ThreadGroup 也有优先级,如果 Thread 的优先级大于 ThreadGroup 的优先级了,那么就以 ThreadGroup 的优先级为准
接下来咱们聊聊关于线程优先级的其他问题
线程优先级是否具有继承性?
如果在线程 A 中启动了线程 B ,此时线程 A 的优先级为 5 , 那么线程 B 的优先级是否也是 5 呢?
答案是: 是的,线程 B 会继承线程 A 的优先级,也就是此时线程 B 的优先级就是 5 .即: 线程优先级具有继承性
我们具体来看例子,具体代码如下:
/**
* @introduce: 验证线程优先级具有继承性
* @author: zll
* @DATE: 2022-3-20 11:44:01
**/
public class ThreadInheritOne extends Thread{
@Override
public void run(){
System.out.println("ThreadInheritOne Priority is " + this.getPriority());
ThreadInheritTwo threadInheritTwo = new ThreadInheritTwo();
threadInheritTwo.start();
}
}
/**
* @introduce: 验证线程优先级具有继承性
* @author: zll
* @DATE: 2022-3-20 12:09:51
**/
public class ThreadInheritTwo extends Thread{
@Override
public void run(){
System.out.println("ThreadInheritTwo Priority is " + this.getPriority());
}
}
/**
* @introduce: 验证线程优先级具有继承性
* @author: zll
* @DATE: 2022-3-20 12:09:51
**/
public class ThreadInheritRun {
public static void main(String[] args) {
System.out.println("main thread start, its priority is " + Thread.currentThread().getPriority());
Thread.currentThread().setPriority(10);
System.out.println("main thread end, its priority is " + Thread.currentThread().getPriority());
ThreadInheritOne threadInheritOne = new ThreadInheritOne();
threadInheritOne.start();
}
}
运行一下以上代码,执行结果如下:
我们能够看到,本来运行的 main 线程优先级是 5 ,后来设置成 10 之后,再在里面启动 ThreadInheritOne
线程,此时它的线程优先级也变成了 10 , ThreadInheritOne
线程里又启动了 ThreadInheritTwo
,此时 ThreadInheritTwo
的线程优先级也是 10
由此,可以验证线程优先级具有继承性
设置线程优先级具有什么意义?
设置线程优先级,我们是肯定希望这个线程相对于其他线程,能够优先被 CPU 执行的,那么这一点怎么验证下呢?
还是来看个例子:
/**
* @introduce: 验证线程优先级高的优先被 CPU 执行
* @author: zll
* @DATE: 2022-3-20 12:26:12
**/
public class ThreadPriorityOne extends Thread{
@Override
public void run(){
long beginTime = System.currentTimeMillis();
long result = 0;
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 50000; j++) {
Random random = new Random();
random.nextInt();
result = result + j;
}
}
long endTime = System.currentTimeMillis();
System.out.println("★★★★★ threadOne priority is relatively high , use time = " + (endTime - beginTime));
}
}
/**
* @introduce: 验证线程优先级高的优先被 CPU 执行
* @author: zll
* @DATE: 2022-3-20 12:26:12
**/
public class ThreadPriorityTwo extends Thread{
@Override
public void run(){
long beginTime = System.currentTimeMillis();
long result = 0;
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 50000; j++) {
Random random = new Random();
random.nextInt();
result = result + j;
}
}
long endTime = System.currentTimeMillis();
System.out.println("☆☆☆☆☆ threadTwo priority is relatively low , use time = " + (endTime - beginTime));
}
}
/**
* @introduce: 验证线程优先级高的优先被 CPU 执行
* @author: zll
* @DATE: 2022-3-20 12:26:12
**/
public class ThreadPriorityRun {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
ThreadPriorityOne threadOne = new ThreadPriorityOne();
threadOne.setPriority(10);
threadOne.start();
ThreadPriorityTwo threadTwo = new ThreadPriorityTwo();
threadTwo.setPriority(1);
threadTwo.start();
}
}
}
来看下代码的运行效果:
上面的截图只是一部分,不过也能让我们发现规律了,就是: 线程优先级高的,会优先被 CPU 执行
你可能会说了,那是当然的,因为在 main 线程中,将 ThreadPriorityOne
线程写在了 ThreadPriorityTwo
线程前面,根据线程调用顺序,此时 main 线程中肯定先执行 ThreadPriorityOne
线程,那么 ThreadPriorityOne
线程优先被执行完也就不足为奇了
那我们将这两个线程的优先级换一下,看看效果(所以代码有些微调整,也就是将 ThreadPriorityOne
的优先级调整为 1 , ThreadPriorityTwo
线程优先级调整为 10 ,相应的文案也进行了调整)
可以看到,尽管 main 线程先调用了 ThreadPriorityOne
线程,但是 ThreadPriorityTwo
线程还是优先被执行了
也就是:线程优先级比较高的话,就会被 CPU 优先执行,和此时 main 线程先调用哪儿个线程没有关系
如果有面试官问你线程有没有优先级,优先级是否能被继承,以及线程优先级高的话,就会被 CPU 优先执行吗
自信点儿
参考:
- Java 多线程编程核心技术
以上,
感谢您的阅读~