守护线程
2021-01-22 16:14
(本文中的全部观点,仅代表个人观点)
主线程、用户线程、守护线程的区分:
主线程:一个进程只有一个主线程(Main),其他都是子线程。(重点:个人认为主线程也是用户线程!!!)
用户线程:非守护线程(这个解释有点......废话)
守护线程:与系统,程序共存亡的线程就是守护线程。最常见的就是GC垃圾回收器。
优先级:用户线程 > 守护线程(这里的优先级并不是指真正的线程优先级)
当jvm里的线程都是守护线程的时候,那么就会自动结束jvm。而当jvm里有其他用户线程的时候,jvm就不会结束。
换句话说,离开jvm的最后一个线程肯定是守护线程,只要有用户线程的存在,那么jvm就不会关闭。
接下来,分析一波代码,真正的理解了下面代码的执行,那么你应该已经能够很好的理解守护线程了。
首先贴出代码:
运行的结果有如下几种情况(注意,并不是只有这些情况,只是我贴出这么几张运行结果图):
以上四种结果,仔细分析,怎么几乎每次的结果都不一样呢?这是为什么?
分析思路:
首先,我们看看代码,我们把thread线程设置成了守护线程。
然后分析,上面的所执行的代码中总共有几个线程?恩......对,三个,1是thread守护线程,2是main主线程,3是啥???
对的,3是GC垃圾回收器。上面已经说过了,我认为主线程依然是用户线程。所以说,主线程未结束,那么守护线程就不会先退出jvm
那么问题来了?主线程什么时候结束?恩......我也不知道。恩,不知道就不知道了,就不要钻牛角尖了,非得知道主线程啥时候结束,线程这种
东西不好控制,不好调试,所以只能根据一个大概的思路去理解。这里我个人已经认为主线程是用户线程了,那么守护线程肯定是比用户线程
晚退出jvm内存的,守护线程在代码中调用了start进入到了就绪状态,等待cpu的调度,分配给他时间片,假如,主线程的结束是在cpu已经把
时间片分给thread守护线程了,那么守护线程自然就要开始执行上面那个死循环,但是具体执行多少次得看主线程啥时候结束,主线程结束
了,那么jvm内存里就只剩下thread守护线程和Gc了,两个守护线程,没有其他用户线程,那么自动退出jvm内存,结束程序。
再假如,主线程的结束在cpu把时间片分给守护线程thread之前,那么自然,thread线程就没有成功执行run方法里的死循环打印程序。(上面第一张执行结果截图),没有用户线程了,那么自然自动退出jvm内存,结束程序。
再看一种情况,如下图:
在代码中,多加一行thread.join(),这回造成什么后果呢?首先我们得明白join()这个方法的含义:阻塞其他线程,一般用于阻塞主线程,让主线程在该线程结束之后再运行。再整体分析,给守护线程thread执行join()方法,那么主线程就被阻塞了,而thread这个守护线程就一直在执行run()方法的死循环,死循环是不可能结束的,然而主线程一直在等thread线程执行结束,可是是等不来结果的。也就是说,主线程不会消失,所以说守护线程也不会因为没有用户线程而消亡。所以结果是:守护线程执行上面死循环,不会终止。
另外!!!
主线程的死亡不会导致jvm内存的关闭,用户线程如果没执行完还会继续执行的。
主线程的死亡会不会导致守护线程的消亡和jvm关闭,得看除了主线程之外,还有没有其它用户线程再执行,如果有的话,jvm内存不会关闭,守护线程也不会消亡。
守护线程的作用:为用户线程的运行提供便利服务。
thread.setDameon(true)应该在thread.start()之前,否者会报错( IllegalThreadStateException)。
最后,给出我写下这篇笔记的参考博客:
1: https://www.cnblogs.com/jerryshao2015/p/4419665.html
2: https://blog.csdn.net/qwdafedv/article/details/84062717