@

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 中, 线程的优先级有如下特点:

  1. Java 线程的优先级从 1~10;
  2. Java 线程默认优先级是 5;
  3. 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() 中去掉一些无关的输出, 最后输入如下:

Java 多线程(二)之 Thread 优先级的更多相关文章

  1. java 多线程二

    java 多线程一 java 多线程二 java 多线程三 java 多线程四 线程中断: /** * Created by root on 17-9-30. */ public class Test ...

  2. Java多线程专题3: Thread和ThreadLocal

    合集目录 Java多线程专题3: Thread和ThreadLocal 进程, 线程, 协程的区别 进程 Process 进程提供了执行一个程序所需要的所有资源, 一个进程的资源包括虚拟的地址空间, ...

  3. Java多线程4:Thread中的静态方法

    一.Thread类中的静态方法 Thread类中的静态方法是通过Thread.方法名来调用的,那么问题来了,这个Thread指的是哪个Thread,是所在位置对应的那个Thread嘛?通过下面的例子可 ...

  4. java多线程(二)-Runnable和Thread

    Java在顺序性语言的基础上提供了多线程的支持.Java的线程机制是抢占式的.这表示调度机制会周期的中断线程,将上下文切换到另一个线程,从而为每个线程都提供时间片.(与抢占式多线程对应的是 协作式多线 ...

  5. 从零开始学习Java多线程(二)

    前面已经简单介绍进程和线程,为后续学习做铺垫.本文讨论多线程传参,Java多线程异常处理机制. 1. 多线程的参数传递 在传统开发过程中,我们习惯在调用函数时,将所需的参数传入其中,通过函数内部逻辑处 ...

  6. Java多线程3:Thread中的实例方法

    一.Thread类中的方法调用方式 学习Thread类中的方法是学习多线程的第一步.在学习多线程之前特别提出一点,调用Thread中的方法的时候,在线程类中,有两种方式,一定要理解这两种方式的区别: ...

  7. Java多线程(二) —— 深入剖析ThreadLocal

    对Java多线程中的ThreadLocal类还不是很了解,所以在此总结一下. 主要参考了http://www.cnblogs.com/dolphin0520/p/3920407.html 中的文章. ...

  8. java 多线程2:Thread的实例方法

    Thread类中的方法调用方式: 学习Thread类中的方法是学习多线程的第一步.在学习多线程之前特别提出一点,调用Thread中的方法的时候,在线程类中,有两种方式,一定要理解这两种方式的区别: 1 ...

  9. java多线程(二)

    线程的阻塞状态: 参考java多线程(一)多线程的生命周期图解,多线程的五种状态.     1.1 join(),如果在A线程体里面执行了B线程的join()方法,那么A线程阻塞,直到B线程生命周期结 ...

  10. Java多线程(二) 多线程的锁机制

    当两条线程同时访问一个类的时候,可能会带来一些问题.并发线程重入可能会带来内存泄漏.程序不可控等等.不管是线程间的通讯还是线程共享数据都需要使用Java的锁机制控制并发代码产生的问题.本篇总结主要著名 ...

随机推荐

  1. Problem5-Project Euler

    Smallest multiple   2520 is the smallest number that can be divided by each of the numbers from 1 to ...

  2. SQLSERVER群集故障转移笔记

    SQLSERVER群集故障转移笔记 出自<SQLSERVER2012实施与管理实战指南> SQLSERVER故障转移 P41 事实上,从sqlserver2000到sqlserver200 ...

  3. [cb]NGUI事件及复杂UI管理

    事件管理 看了有些文章关于NGUI的事件管理,许多人的做法的是封装一个事件处理层,避免在每个UI控件上都绑定事件处理脚本.本文说说我们项目中的UI事件管理吧. UIEventListener 我们项目 ...

  4. entityFramework 中decimal精度缺失问题

    在entityFramework中,decimal精度默认为2位数,当要设置的精度大于2位并且数据库中设置的decimal精度大于2位时,则将数据保存在数据库中后两位的小数内容将强制为00 解决方案: ...

  5. 乘风破浪:LeetCode真题_034_Find First and Last Position of Element in Sorted Array

    乘风破浪:LeetCode真题_034_Find First and Last Position of Element in Sorted Array 一.前言 这次我们还是要改造二分搜索,但是想法却 ...

  6. WaitForMultipleObjects

    WaitForMultipleObjects是Windows中的一个功能非常强大的函数,几乎可以等待Windows中的所有的内核对象 函数原型为: DWORD WaitForMultipleObjec ...

  7. sql点滴44—mysql忘记root密码

    1. 首先检查mysql服务是否启动,若已启动则先将其停止服务,可在开始菜单的运行,使用命令: net stop mysql 打开第一个cmd1窗口,切换到mysql的bin目录,运行命令: mysq ...

  8. python3: 数字日期和时间(2)

    12.基本的日期与时间转换 Q: 你需要执行简单的时间转换,比如天到秒,小时到分钟等的转换 A: 为了执行不同时间单位的转换和计算,请使用 datetime 模块. 比如,为了表示一个时间段,可以创建 ...

  9. 团队作业——Alpha冲刺 3/12

    团队作业--Alpha冲刺 冲刺任务安排 杨光海天 今日任务:完成Android开发环境的搭建,学习基础开发知识 明日任务:继续学习Android开发知识,与其他成员协商,了解自己需要完成的开发任务, ...

  10. 矿难让显卡压了那么多货咋办?NV如是说

    在苏州 GTC 开幕的几天前,英伟达刚刚遭遇了一次股价的腰斩. 近来加密货币的热度渐低,受到挖矿热潮照顾许多的英伟达「矿机」销量受到打击,甚至出现了严重的库存危机,加上近来刚刚发的 RTX20 系列显 ...