线程的四个属性
线程各属性纵览
属性名称 | 用途 | 注意事项 |
---|---|---|
ID | 每个线程都有自己的ID,用于识别不同的线程 | 被后续创建的线程使用;不允许被修改 |
Name | 便于用户在开发、调试或运行过程中区分每个不同的线程、定位问题等 | 清晰有意义的名字;默认的名称 |
isDaemon | true:代表是守护线程,false:非守护线程(用户线程) | 继承父线程;setDaemon |
Priority | 优先级,是告诉线程调度器,用户希望哪些线程相对多运行、哪些少运行 | 默认和父线程的优先性相等;不应该依赖优先级;默认5,最大10 |
线程Id
Id 是自增的,默认threadSeqNumber初始化值为 0,但因为是先++,因此第一个线程(main线程)的Id 为 1。
得出结论,线程 Id 是从 1 开始的。
private static synchronized long nextThreadID(){
return ++threadSeqNumber;
}
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 开始自增
public Thread(){
init(null,null,"Thread-"+nextThreadNum(),0);
}
源码中可看到,后++,因此从 0 开始
和 ID 相同,它们都是被synchronized修饰的,因此在多线程下不会出现重复的Id和Name
private static int threadInitNumber;
private static synchronized int nextThreadNum(){
return threadInitNumber++;
}
如果要设置线程名称,可以在构建线程时传入,如 new Thread(“orcas”);
也可以在之后通过调用 setName(String name) 方法设置
public final synchronized void setName(String name){
checkAccess();
if(name==null){
throw new NullPointerException("name cannot be null");
}
this.name=name;
if(threadStatus!=0){
setNativeName(name);
}
}
除了线程内部的 name 属性,还有一个 nativeName 属性,它的set方法被native修饰,是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,最小是1
程序设计不该依赖于优先级:
优先级高度依赖操作系统,不同操作系统对于优先级的映射、调度不一样
系统中有一个优先级推进器,它会更改优先级。