1. 考考你
- 什么时候我们需要设置守护线程?
- 我们应该如何应用线程优先级来帮助程序运行?有哪些禁忌?
- 不同的操作系统如何处理优先级问题?
2. 线程各属性纵览
属性名称 | 用途 |
---|---|
编号(ID) | 每个线程都有自己的ID,用于标识不同的线程 |
名称(Name) | 让用户或程序员在开发、调试或运行过程中,更容易区分每个不同的线程、定位问题等 |
是否是守护线程(isDaemon) | true代表该线程是【守护线程】,false代表线程是非守护线程,也就是【用户线程】 |
优先级(Priority) | 告诉线程调度器,用户希望哪些线程相对多运行、哪些少运行。 |
3. 线程Id
Returns the identifier of this Thread. The thread ID is a positive long number generated when this thread was created. The thread ID is unique and remains unchanged during its lifetime. When a thread is terminated, this thread ID may be reused.
返回线程的唯一标识。线程在创建时会生成一个正整数作为ID,线程 ID 是唯一的,并且在其生命周期内保持不变。当一个线程终止时,这个线程 ID 可能会被重用。
- 查看生成ID的源码
/*
* Thread ID
*/
private long tid;
/* For generating thread ID */
private static long threadSeqNumber;
tid = nextThreadID();
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
}
4. 线程 名字
- 默认线程名字源码分析
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
- 修改线程的名字(代码演示、源码分析)
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);
}
}
自定义线程名:
new Thread(threadId,"MyThread").start();
Thread thread = new Thread(() -> {
System.out.println("Current thread id is " + Thread.currentThread().getId() + " name " + Thread.currentThread().getName());
});
thread.setName("MyThread2");
thread.start();
5.守护线程
Marks this thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads.
This method must be invoked before the thread is started.
将此线程标记为守护线程或用户线程。 当运行的线程都是守护线程时,Java 虚拟机退出。
该方法必须在线程启动之前调用。
- 设置守护线程的方法
Thread thread = new Thread(() -> {
System.out.println("Current thread id is " + Thread.currentThread().getId() + " name " + Thread.currentThread().getName());
});
thread.setDaemon(true);
- 作用
给用户线程提供服务。
JVM
能关闭的线程是守护线程。垃圾处理器就是守护线程。
-
3个特性
- 线程的类型默认
继承
自父线程。 被谁
启动:由JVM启动。不影响
JVM退出:只有用户线程会影响。
- 线程的类型默认
-
守护线程和普通线程的区别
- 整体
无
区别 唯一
区别在于JVM的离开。
- 整体
-
我们
是否需要
给线程设置为守护线程?
不是是否需要,而是是否应该,答案是不应该,不应该把自己的线程设置为守护线程。一旦设置为守护线程会变得非常危险,比如该线程正在操作文件,JVM发现当前运行的线程都是守护线程,此时JVM就会退出,从而出现数据不一致的情况。
6. 线程优先级
-
10个级别,默认5
-
程序设计不应依赖于优先级
- 不同操作系统不一样
- 优先级会被操作系统改变
7. 各属性总结
属性名称 | 用途 | 注意事项 |
---|---|---|
编号(ID) | 标识不同的线程 | 被后续创建的线程使用;唯一性;不允许被修改 |
名称(Name) | 定位问题 | 清晰由意义的名字;默认的名称 |
是否是守护线程(isDaemon) | 守护线程、用户线程 | 二选一;继承父线程;setDaemon |
优先级(Priority) | 相对多运行 | 默认和父线程的优先级相等,共有10个等级,默认是5;不应依赖线程优先级做业务处理 |
8.面试
常见问题
- 什么时候我们需要设置守护线程
通常情况下不需要设置守护线程,JVM所提供的守护线程足够我们使用。
- 我们应该如何让应用线程优先级来帮助程序运行?有哪些禁忌?
我们不应该使用程序优先级来帮助程序运行,因为不同操作系统对优先级的处理不同。
- 不同的操作系统如何处理优先级问题?
不同的操作系统对优先级的处理、调度都不一样,还有可能被操作系统所忽略,所以不应该用优先级做业务处理。