- 线程分为
User Thread(用户线程)
和Daemon Thread(守护线程)
- 虚拟机必须确保
用户线程
执行完毕- 虚拟机不用等待
守护线程执
行完毕- 如:后台记录操作日志、监控內存、垃圾回收等
- 操作
- 通过
thread.setDaemon(true)
将线程转换为守护线程,这个方法必须在thread.start()
之前进行调用
1、守护线程简介
参考资料:Java中的守护线程
守护线程的功能非常简单,在其本身是一个线程的同时,主要是为了给其他的线程提供服务,比如说计时器,清空高速缓存等等操作,守护线程具有和被守护线程一样的生命周期(这里并不是说守护线程和被守护线程常常是1对1的关系),当被守护线程死亡,守护线程往往也会死亡,当虚拟机中只剩下守护线程时,虚拟机就会退出,因为此时也没有运行程序的必要了
一个比较通俗的解释:任何一个守护线程都是整个JVM中所有非守护线程的保姆
只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。
守护线程的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是 GC (垃圾回收器),它就是一个很称职的守护者
2、需要注意的点
- 守护线程的优先级比较低
- 守护线程要注意考虑关机动作
- 守护线程应该永远不去访问固有资源,比如说文件或者数据库,因为它会在任何时候甚至一个操作的中间发生中断
- 不要给守护线程分担读写逻辑或者计算逻辑,因为无法确定守护线程是否已经完成了工作,但是只要User退出守护线程也会立马结束,对于计算机程序来说这样的程序可能多次运行结果不一样,很显然这对于程序来说是毁灭性的
3、CODE
package mii.thread.demo12守护线程;
public class TestDeamon02 {
public static void main(String[] args) {
// 守护线程
Thread deamonThread = new Thread(()->{
for (;;){
System.out.println(Thread.currentThread().getName() +
"__在幕后默默守护着...");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "守护线程");
// 用户线程
Thread userThread = new Thread(()->{
int age = 0;
while (age < 100) {
age++;
System.out.println(Thread.currentThread().getName() +
"__已经" + age + "岁了,正在努力奋斗!");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "__挂了!");
}, "小明");
deamonThread.setDaemon(true); // 默认false
deamonThread.start();
userThread.start();
}
}