一直想整理一下线程方面的知识,线程无处不在,这部分在开发中零零散散的用到,所以一直想把自己用到过的知识点整理一下,今天先提一下守护线程。
什么是守护线程?
我所理解的守护线程就像是绑定了我们程序的一个线程,程序在的时候它才可能存在(不一定存在,要看我们什么时候start()),程序结束他也就结束了。当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。一句话不求同年同月同日生,但求同年同月同日死,哈哈。垃圾回收线程就是一个很称职的守护线程,一旦程序结束,它也就没有存在的必要了。
例如Timer:Timer中就创建了一个线程,无意中发现创建Timer实例的时候会有一个传入boolean值得构造方法。查看之下才知道是设置Timer中的线程性质的,当true的时候就创建一个守护线程,否则为非守护线程。区别用代码来看
public static void main(String[] args) {
Timer timer=new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("我执行了。。。。。");
}
}, 1000);
System.out.println("程序结束。。。。");
}
一般使用时,打印如下:
程序结束。。。。
(约1s)我执行了。。。。。
而当我们把上面的实例改为Timer timer=new Timer(true);也就是守护线程时,打印结果变成了:
打印结果就变成了只有: 程序结束。。。。
显然守护线程在程序退出后就不再执行了。
相对来说用户线程(非守护线程)就好理解了,我们平时开发没有特意设置的线程都是非守护线程,只要他们还在运行,程序就不会终止。
所以非守护线程是否运行---》决定了程序是否还在运行——》决定了守护线程是否还在运行
守护线程和用户线程的没啥本质的区别:唯一的不同之处就在于虚拟机的离开:如果用户线程已经全部退出运行了,只剩下守护线程存在了,虚拟机也就退出了。所以应该避免在守护线程中读写固有资源等操作如文件、数据库,因为它会在任何时候甚至在一个操作的中间发生中断。
另外还需要注意:
a. setDaemon(boolean b)可以用来设置线程是否是守护线程。thread.setDaemon(true)必须在thread.start()之前设置,并且不能把正在运行的常规线程设置为守护线程
b. 在Daemon线程中产生的新线程也是Daemon的。