一 点睛
1 设置和获取线程优先级
// 为线程设置优先级
public final void setPriority(int newPriority)
// 获取线程优先级
public final int getPriority()
2 说明
进程有进程的优先级,线程也有优先级,理论上是优先级比较高的线程会获得优先被 CPU 调度的机会,但事实上往往并不是这样,设置线程的优先级同样是一个提示操作,具体如下。
- 对于 root 用户,它会提示操作系统你想要设置的优先级别,否则它会被忽略。
- 如果 CPU 比较忙,设置优先级可能会获得更多的 CPU 时间片,但是闲时优先级的高低几乎不会有任何作用。
所以,不要在程序设计当中企图使用线程优先级绑定某个特定的业务,或者让业务严重依赖线程的优先级。
二 实战
1 代码
package concurrent;
public class ThreadPriority {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
while (true) {
System.out.println("t1");
}
});
t1.setPriority(3);
Thread t2 = new Thread(() -> {
while (true) {
System.out.println("t2");
}
});
t2.setPriority(10);
t1.start();
t2.start();
}
}
2 测试
运行上面的程序,会发现 t2 出现频率很明显要高一些。
三 线程优先级源码分析
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);
}
}
通过分析,可以看到,线程的优先级不能能小于 1 或大于 10,如果指定的线程优先级大于线程所在的 group 的优先级,那么指定的优先级将会被失效,取而代之的是 group 的最大优先级。
package concurrent;
public class ThreadPriority2 {
public static void main(String[] args) {
// 顶一个线程组
ThreadGroup group = new ThreadGroup("test");
group.setMaxPriority(7);
Thread t1 = new Thread(group, "test-thread");
t1.setPriority(10);
System.out.println(t1.getPriority());
}
}
测试结果
7
四 小结
一般情况下,不会对线程设定优先级,更不会让某些业务严重依赖线程的优先级,比如权重,借助优先级设定某个任务的权重,这种方式是不可取的,一般定义线程的时候使用默认优先级就好了。
线程默认优先级别和它的父类保持一致,一般情况下都是5,main 线程的优先级就是 5,所以它派生出的线程都是5
package concurrent;
public class ThreadPriority3 {
public static void main(String[] args) {
Thread t1 = new Thread();
System.out.println("t1 priority " + t1.getPriority());
Thread t2 = new Thread(() -> {
Thread t3 = new Thread();
System.out.println("t3 priority " + t3.getPriority());
});
t2.setPriority(6);
t2.start();
System.out.println("t2 priority " + t2.getPriority());
}
}
测试结果如下
t1 priority 5
t2 priority 6 // 显示设置了优先级
t3 priority 6 // 和父线程保持一致