守护线程和非守护线程
直觉上来讲,守护线程和main相关
Java中有两种线程,一种是用户线程,另一种是守护线程。
用户线程是指用户自定义创建的线程,主线程停止,用户线程不会停止(另一条执行路径)
守护线程当进程不存在或主线程停止,守护线程也会被停止。
我们自己创建的线程叫 用户线程 如果主线程停止掉 不会影响用户线程(非守护线程)
Java中 不光有主线程还有GC线程
主线程销毁之后 GC线程也跟着一起销毁
用户线程和守护线程的适用场景
由两者的区别及dead时间点可知,守护线程不适合用于输入输出或计算等操作,因为用户线程执行完毕,程序就dead了,适用于辅助用户线程的场景,如JVM的垃圾回收,内存管理都是守护线程,还有就是在做数据库应用的时候,使用的数据库连接池,连接池本身也包含着很多后台线程,监听连接个数、超时时间、状态等。
主线程死掉后 就不需要回收垃圾了 主程序死掉了 进程挂了都 gc线程主要回收主线程里面的 有专门回收子线程垃圾的线程
守护线程和用户线程的没啥本质的区别:唯一的不同之处就在于虚拟机的离开:如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。 因为没有了被守护者,守护线程也就没有工作可做了,也就没有继续运行程序的必要了。
总结:没有啥子线程时候,守护线程会被杀死,会退出
我总结了个小demo,大家可以跑一跑,就是个排列组合,大家看看怎么回事儿
主线程 守护线程 用户线程
三个 排列组合
看看效果
package com.toov5.thread; public class DaemonThread { public static void main(String[] args) { Thread thread = new Thread(new Runnable() { public void run() { while (true) { try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("守护子线程"); } } } ); thread.setDaemon(true); thread.start(); // // new Thread(new Runnable() { // public void run() { // while (true) { // try { // Thread.sleep(100); // } catch (InterruptedException e) { // e.printStackTrace(); // } // System.out.println("非守护子线程1"); // } // } // } ).start(); new Thread(new Runnable() { public void run() { for (int i=0;i<100;i++) { try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("非守护子线程2"); } } } ).start(); for(int i=0; i<10;i++){ try { Thread.sleep(100); } catch (Exception e) { // TODO: handle exception } // System.out.println("主线程"); } System.out.println("主线程执行完毕!!!!!!!!!!!!!!!!"); } }
大家看看输出结果就明了了
总结: jvm主线程、用户线程都挂掉时候,守护线程也会退出。