线程属性概览
属性名称 | 用途 | 注意事项 |
---|---|---|
id | 每个线程都有自己的ID,用于识别不同的线程 | 不允许被修改 |
name | 便于用户在开发、调试或运行过程中区分每个不同的线程或定位问题等 | 有默认的名称,用户自定义线程名称时,尽量定义的清晰有意义 |
isDaemon | true:代表是守护线程,false:代表是非守护线程(用户线程) | 会继承父线程是否是守护线程的属性 |
priority | 线程优先级,是告诉线程调度器,用户希望哪些线程在调度过程中更容易获得CPU资源 | 线程默认和父线程的优先性相等,不应该依赖线程优先级进行编程 |
线程 id
ID是自增的,默认threadSeqNumber初始值为0,但因为是先++,因此第一个线程(main线程)的ID为 1。
得出结论,线程ID是从1开始的。
ID从1开始在下列代码中得到了验证,但为什么我们新建的子线程的ID却是从11开始呢?
public class Id {
public static void main(String[] args) {
Thread thread = new Thread();
Thread thread2 = new Thread();
System.out.println(Thread.currentThread().getName() + " 的Id : " + Thread.currentThread().getId());
System.out.println(thread.getName() + " 的Id : " + thread.getId());
System.out.println(thread2.getName() + " 的Id : " + thread2.getId());
}
}
main 的Id : 1
Thread-0 的Id : 11
Thread-1 的Id : 12
我们在Debugger的Threads窗口可以看到,JVM帮我们创建了多个守护线程。
(Debug模式启动后,最后输出变为了 13、14,所以Debug模式会多启2个线程)。
线程名称 name
默认线程名称从Thread-0开始自增。
源码中可看到,后++,因此从0开始。
和ID相同,它们都是被synchronized修饰的,因此在多线程下不会出现重复的ID和name。
如果要设置线程名称,可以在构建线程时传入,如new Thread(“orcas”)。
也可以在之后通过调用setName(String name)方法设置(线程未启动前)。
除了线程内部的name属性,还有一个nativeName属性,它的set方法被native修饰,是c/c++层的名称,if判断语句表示当线程启动时(threadStatus=0表示线程未启动),不能再修改nativeName。
守护线程 daemon
- 作用:给用户线程提供服务。
- 特性:线程类型默认继承自父线程,JVM自动启动,不影响JVM退出。
- 与普通线程的区别:整体无区别,唯一的区别在于是否影响JVM退出,用户线程是执行逻辑的,守护线程是服务用户线程的。
是否需要给线程设置为守护线程?
不该设置为守护线程,一旦把用户线程设置为守护线程,当剩下的全部都是守护线程时,JVM会退出,使正在执行的逻辑中断,导致数据不一致。
线程优先级 priority
public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;
线程优先级有10个级别,默认5,最大是10,最小是1。
不该依赖于线程优先级
线程优先级的实现高度依赖操作系统,不同操作系统对于优先级的映射、调度不一样,系统中有一个优先级推进器,它会更改优先级。