前言
本文隶属于专栏《100个问题搞定Java并发》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢!
本专栏目录结构和参考文献请见100个问题搞定Java并发
正文
守护线程
如果你希望创建一个线程来执行一些辅助工作,但又不希望这个线程阻碍JVM的关闭。在这种情况下就需要使用守护线程(Daemon Thread)。
守护线程是一种特殊的线程,就和它的名字一样,它是系统的守护者,在后台默默地完成一些系统性的服务,比如垃圾回收线程、JIT线程就可以理解为守护线程。
用户线程
与之相对应的是用户线程,用户线程可以认为是系统的工作线程,它会完成这个程序应该要完成的业务操作。
如果用户线程全部结束,则意味着这个程序实际上无事可做了。守护线程要守护的对象已经不存在了,那么整个应用程序就应该结束。
因此,当一个Java应用内只有守护线程时,Java虚拟机就会自然退出。
主线程
在JM启动时创建的所有线程中,除了主线程以外,其他的线程都是守护线程。
当创建个新线程时,新线程将继承创建它的线程的守护状态,因此在默认情况下,主线程创建的所有线程都是用户线程。
区别
用户线程与守护线程之间的差异仅在于当线程退出时发生的操作。
当一个线程退出时,JVM会检查其他正在运行的线程,如果这些线程都是守护线程,那么JVM会正常退出操作。
当JVM停止时,所有仍然存在的守护线程都将被抛弃。
实践
创建一个守护线程
package com.shockang.study.java.concurrent.thread.daemon;
import java.util.concurrent.TimeUnit;
public class DaemonDemo {
public static class DaemonThread extends Thread {
public void run() {
for (; ; ) {
System.out.println("I am alive");
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread t = new DaemonThread();
t.setDaemon(true);
t.start();
TimeUnit.MILLISECONDS.sleep(2000);
}
}
控制台输出
/Library/Java/JavaVirtualMachines/jdk1.8.0_192.jdk/Contents/Home/bin/java ...
I am alive
I am alive
Process finished with exit code 0