Java中的线程分为两类,守护线程(daemon)和用户线程(user)。JVM启动时会调用main函数,而main函数所在的线程就是一个用户线程。同时,JVM内部还启动了多个守护线程,比如垃圾回收线程。
创建守护线程示例代码:

图 1-1 创建守护线程
创建用户线程示例代码:

图 1-2 创建用户线程
当最后一个非守护线程结束时,JVM会正常退出,而不管当前是否有守护线程。即只要有一个用户线程还没结束,JVM就不会退出。
验证代码:

图 1-3 验证代码
运行结果:

图 1-4 运行结果
前面提到main函数所在的线程也是用户线程,现在主线程结束了,通过jps查看发现JVM进程并没有退出,如下:

图 1-5 jps执行结果
这个结果说明了,父线程(上面例子中main函数所在的线程)结束后,子线程(上面例子中的userThread)还是可以继续执行,即子线程的生命周期并不受父线程影响。也表明用户线程还存在的情况下,JVM进程不会终止。
现在将上面例子改为守护线程,那么结果会怎么样呢,上代码:

图 1-6 验证代码
运行结果:

图 1-7 运行结果
同样的,通过jps查看一下进程情况:

图 1-8 jps执行结果
从运行结果可以发现,main函数所在的线程是唯一的用户线程,随着main函数所在线程运行结束,JVM发现已经没有用户线程了,就会终止JVM进程,即便daemonThread守护线程的执行体是一个死循环,也不会影响这个结果。
总结:如果希望在主线程结束后JVM进程马上结束,那么在创建线程时可以将其设置为守护线程,如果希望在主线程结束后子线程继续工作,那么就将子线程设置为用户线程。