Thread 中线程优先级相关属性
每个线程均有优先级, 在 Thread 中, 与优先级对应的属性如下:
- /**
- * 线程的优先级属性
- */
- private int priority;
- /**
- * 线程所能拥有的最大优先级.
- */
- public final static int MIN_PRIORITY = 1;
- /**
- * 线程默认的优先级.
- */
- public final static int NORM_PRIORITY = 5;
- /**
- * 线程所能拥有的最大优先级.
- */
- public final static int MAX_PRIORITY = 10;
相关函数
在此只讨论 Thread 类中的.
优先级初始化
- private void init(ThreadGroup g, Runnable target, String name,
- long stackSize, AccessControlContext acc) {
- // ....
- this.priority = parent.getPriority();
- setPriority(priority);
- // ....
- }
init() 函数对优先级进行了初始化. 并调用 setPriority(priority) 函数进行设置. 从中得知, 线程的优先级是继承于创建它的线程的.
设置优先级
在 init() 中, 除了给 this.priority 赋值, 还调用了 setPriority(priority) 函数, 因为在该函数内部还调用了一个 native 方法.
- public final void setPriority(int newPriority) {
- ThreadGroup g;
- checkAccess();
- // 不能大于最大优先级 MAX_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);
- }
- }
由代码可知, 设置的优先级不能大于最大优先级, 也不能大于所在线程组的最高优先级
获取优先级
获取当前的优先级, 其实就是返回 priority 属性的值.
- public final int getPriority() {
- return priority;
- }
从以上可知, 在 Thread 中, 线程的优先级有如下特点:
Java 线程的优先级从 1~10;
Java 线程默认优先级是 5;
Java 线程的优先级继承于创建它的线程.
是不是感觉 2 和 3 有所矛盾呢? 可以在后面的代码和结果中找答案.
默认优先级
先上代码来感受一下线程优先级的作用:
- public class ThreadPriorityTest {
- class PrimeRun implements Runnable {
- public void run() {
- System.out.println(Thread.currentThread().getName() +"::"+
- Thread.currentThread().getPriority());
- System.out.println(Thread.currentThread().getName() + "Run begin");
- for (int i = 0; i < 10; i++) {
- System.out.println(Thread.currentThread().getName()+"::"+i);
- }
- System.out.println(Thread.currentThread().getName() + "Run end");
- }
- }
- public void test(){
- System.out.println(Thread.currentThread().getName()+"begin");
- Thread p4 = new Thread(new PrimeRun());
- Thread p6 = new Thread(new PrimeRun());
- p4.setName("P4");
- p6.setName("P6");
- p4.start();
- p6.start();
- System.out.println(Thread.currentThread().getName()+"end");
- }
- public static void main(String[] args) {
- new ThreadPriorityTest().test();
- }
- }
在 PrimeRun 类的 run() 方法中, 只是对 0 到 10 进行输出, 前面加上线程名字以识别. 没有对线程进行设置, 按以上分析的 init() 方法可知, 优先级继承于 ThreadPriorityTest 中的优先级, 没进行设置优先级默认为 5. 输出如下:
可以看到 p4 和 p6 的线程优先级都是 5, 输出是无序的, P4 和 P6 交叉输出, 因此每次的结果都不一样.
指定优先级
将线程中的优先级改一下, test() 函数变成如下:
- public void test(){
- System.out.println(Thread.currentThread().getName()+"begin");
- Thread p4 = new Thread(new PrimeRun());
- Thread p6 = new Thread(new PrimeRun());
- p4.setName("P4");
- p4.setPriority(4);
- p6.setName("P6");
- p6.setPriority(6);
- p4.start();
- p6.start();
- System.out.println(Thread.currentThread().getName()+"end");
- }
在运行之后的输出如下:
可以看到, P6 先于 P4 运行完.
注意事项
但是 (一般 但是 后面的东西都要注意)
优先级和操作系统及虚拟机版本相关.
++ 优先级只是代表告知了 线程调度器该线程的重要度有多大. 如果有大量线程都被堵塞, 都在等候运
行, 调试程序会首先运行具有最高优先级的那个线程. 然而, 这并不表示优先级较低的线程不会运行 (换言之, 不会因为存在优先级而导致死锁). 若线程的优先级较低, 只不过表示它被准许运行的机会小一些而已.++
因此, 在实际的编码时, 认为高优先级一定先于低优先级的线程执行, 最后会出问题的.
优先级继承
而关于特点 2 和 3 的区别, 我们在第一次 test() 时, P4 和 P6 的优先级都是 5, 我们将函数改一下:
- public void test(){
- Thread.currentThread().setPriority(10);
- System.out.println(Thread.currentThread().getName()+"begin");
- Thread p4 = new Thread(new PrimeRun());
- Thread p6 = new Thread(new PrimeRun());
- p4.setName("P4");
- p6.setName("P6");
- p4.start();
- p6.start();
- System.out.println(Thread.currentThread().getName()+"end");
- }
在创建 P4 和 P6 之前将当前线程的优先级设置为 10, 并在 run() 中去掉一些无关的输出, 最后输入如下:
来源: https://www.cnblogs.com/homejim/p/9527226.html