守护线程和非守护线程
直觉上来讲,守护线程和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("主线程执行完毕!!!!!!!!!!!!!!!!");
}
}
大家看看输出结果就明了了