Interrupt学习:
在jdk中关于interrupt相关方法有三个,如下:
![](https://i-blog.csdnimg.cn/blog_migrate/bea59d368cb5b7f95e4381149a9ac36b.png)
关于上面的疑问会在稍后进行阐述滴,下面看代码:
![](https://i-blog.csdnimg.cn/blog_migrate/897e2b97c579de864eee76014311f881.png)
编译运行:
![](https://i-blog.csdnimg.cn/blog_migrate/8d12da1fe3b095030ba87ea7d6bfead8.png)
应该说是t线程为啥在被打断之后没有退出,还是在运行状态,这时由于它没有捕获这个中断,在捕获中断之前先看一下官方对于interrupt()的一些说明:
![](https://i-blog.csdnimg.cn/blog_migrate/833d6ff14c651c7fda37fe6565c98ad0.png)
那难道在线程中不调用上述的三个方法在线程被中断之后就收不到中断异常了么?下面来试验下:
![](https://i-blog.csdnimg.cn/blog_migrate/397ce43364d36529cfb2b8f54d1765a4.png)
![](https://i-blog.csdnimg.cn/blog_migrate/406f9f915d73cdde5a10c6f1773c9641.gif)
可以看到也可以正常的读取到中断的状态,那看一下interrupt()的源码:
![](https://i-blog.csdnimg.cn/blog_migrate/73475053bc094d9ba2ef26cba20f7cde.png)
而jdk中所说的自动捕获中断异常的话则需要调用文中所说的三个方法,所以下面用一下捕获中断异常,首先先调用sleep的方式让线程小睡一会:
![](https://i-blog.csdnimg.cn/blog_migrate/869e940537ea8dff8e325bffe227e254.png)
接着再来试用利用wait()让线程等待,当然这个目前还木有学到,后面会学滴,这里只是了解下在wait()的时候是需要加上锁滴:
![](https://i-blog.csdnimg.cn/blog_migrate/9ab6a3ca42f2c1de6fbf11ffd0cee8bd.png)
嗯,同样也捕获到了中断异常,但都没有让t线程退出,那有没有现成的API能让线程主动停止呢?当然有,但是官方不推荐使用,因为会存在问题,但是!!这里以玩的心态试下效果:
![](https://i-blog.csdnimg.cn/blog_migrate/f46aee06ed8a01bf794e485165fa6cc4.png)
![](https://i-blog.csdnimg.cn/blog_migrate/298f984f19e2fc99bc22534ab27d36fb.gif)
嗯~~确实是管用能让线程停止,但是!!实际中没有这样用的~~纯实验。
接着来解决开篇所提出的疑问:
![](https://i-blog.csdnimg.cn/blog_migrate/b87428e7bc38797520a0ee17fe3662e6.png)
其实是有存在的必要的,下面看代码:
![](https://i-blog.csdnimg.cn/blog_migrate/36b92d8b2228c01e69894656d6e746a0.png)
这时就只能用这个static的方法来判断啦:
![](https://i-blog.csdnimg.cn/blog_migrate/21a3ff6cf9c68747a3769027f4d5f38e.png)
而其实它就是获得当前的线程,然后再调用它的isInterrupted()方法,源码如下:
![](https://i-blog.csdnimg.cn/blog_migrate/ca671b5f33dfff3bcf0d215834f57d7a.png)
最后再来用JDK中提到的join()方法来捕获下中断异常,如下:
![](https://i-blog.csdnimg.cn/blog_migrate/d57252e1b8f276552a2832faa88d0b1e.png)
这时就得分析一下join()线程的情况啦,很显然join()的是main线程,而我们打断的是t线程,那主线程的join()当然就收不到中断异常啦,所以基于这个理论下面来改造代码让咱们的join()能收到异常捕获:
![](https://i-blog.csdnimg.cn/blog_migrate/e07d15b3e9f36f3e30c95b9c1a6a47a0.png)
这时再运行:
![](https://i-blog.csdnimg.cn/blog_migrate/e4bd3a94064a7e61608cda9bac9f289c.png)
其实join()方法的实现也是采用了wait()方式,如下:
![](https://i-blog.csdnimg.cn/blog_migrate/252fe99923224910dd952250493a7f89.png)
另外还有一个细节需要注意:
![](https://i-blog.csdnimg.cn/blog_migrate/0d472ea0bb2fc97a47af7fe720b009cc.png)
采用优雅的方式结束线程生命周期:
由于Thread.stop()方法不能用了,而有了上面的打断机制,下面就来探讨下如何优雅的将线程退出。
方式一、用一个标记来控制【实际中经常使用到】
![](https://i-blog.csdnimg.cn/blog_migrate/cfc87c0157978c061326840c115f26b7.png)
编译运行:
![](https://i-blog.csdnimg.cn/blog_migrate/e31e5590964f4a2b5192bebd2b357194.gif)
方式二、利用打断机制:
![](https://i-blog.csdnimg.cn/blog_migrate/5405f46c4ee25bdb38702ea0336a9f00.png)
或者不去捕获异常,而是直接通过状态判断去控制:
![](https://i-blog.csdnimg.cn/blog_migrate/f13819a35462375fae061ee0fcdc1c84.png)
编译运行:
![](https://i-blog.csdnimg.cn/blog_migrate/1bf67208a6eb3e34e55d129fc0512116.gif)
但是思考这样一种情况:假如在线程执行过程中有一个非常耗时的操作,比如说访问网络之类的,那既始有上面两种优雅退出的方案,但是由于被这个方法阻塞住无法立即退出线程,如:
![](https://i-blog.csdnimg.cn/blog_migrate/a85c4ceb967e64322162dd41518e75ee.png)
那对于这种特殊情况如何也能做到及时让线程进行退出呢?这个就留到下次解决~