daemon线程既守护线程,而在jdk中对于Thread中针对守护线程有专门的API,如下:
![](https://img-blog.csdnimg.cn/img_convert/d00c036c9edefb4e4ed6bd262695b215.png)
而之前在公司项目中就看到过有人使用过Thread中的这个API,但是对于它的使用场景完全不知,所以这次好好的学习一下,下面直接上代码来阐述它。
![](https://img-blog.csdnimg.cn/img_convert/f8c7490926f2a7ea548c95c3d67e8906.png)
编译运行:
![](https://img-blog.csdnimg.cn/img_convert/14c5f7c0271053f941463b3f9d61fc56.png)
很简单,但是这里可以看到在main函数执行完成之后【关于main函数是否真的退出可以用jconsole去查看一下既可,之前也已经查看过】,咱们新创建的Thread-0线程并未退出,这时由于咱们的Thread-0线程还是属于活跃状态,并未执行完,那接下来给我们的线程设置一个daemon属性再看结果,如下:
![](https://img-blog.csdnimg.cn/img_convert/6ae35791c4595ede1ad822e5259fae5a.png)
编译运行:
![](https://img-blog.csdnimg.cn/img_convert/f929e6d5a7966c57fb58eac828ddd436.gif)
可见这时当main线程一结束,其我们的线程也退出了。这也是使用守护之后的一个直观效果,而实用价值其实也是蛮大的,这时可以联想到一个实际要使用daemon线程的场景:客户端与服务器端建立一个TCP的长链接,然后当连接建立之后就创建一个线程来给服务器发送心跳包以便服务器能监听客户端的网络状态,这时如果连接断开了那这个心跳线程也得跟着断开,下面来模拟一下:
![](https://img-blog.csdnimg.cn/img_convert/033f6df61a6bec64c0ce0bbaeff5e690.png)
编译运行:
![](https://img-blog.csdnimg.cn/img_convert/24092d96cd42b6f19d784102c8a3ba83.gif)
发送t线程一执行完,在里面创建的心跳线程也立马终止了,刚好满足我们的场景需求,而如果不给心跳线程设置成deamon线程再看结果:
![](https://img-blog.csdnimg.cn/img_convert/f55183709314b547d0969edef765cd9c.png)
![](https://img-blog.csdnimg.cn/img_convert/d392ca54fee7e7469e50844d5263968c.gif)
很显然当t线程结束之后里面的心跳线程就不会退出了,当然啦不通过给心跳线程设置守护线程也能达到当连接断开之后其心跳线程也退出,自己写逻辑控制既可,但是有了守护线程那这个逻辑我们就可以避免自己写了。
下面再来细读一下jdk对它的描述:
![](https://img-blog.csdnimg.cn/img_convert/9d328b37f1ae9281e3bf606ab96994d8.png)
那不信这个邪,来试一下:
![](https://img-blog.csdnimg.cn/img_convert/9bc8dce5dc7a9409d8f41283cac70be8.png)
编译运行:
![](https://img-blog.csdnimg.cn/img_convert/1bbcf829bf23b79049f0b207e6937f86.png)
这个异常在JDK中也有描述,如下:
![](https://img-blog.csdnimg.cn/img_convert/6618d7cd017204f8f95760d419228f28.png)