如何正确的停止一个线程?
2018-11-15 本文已影响0人
Hoker_
实际项目中,有时候需要中断另外一个线程,早期可以使用stop()方法,但由于stop强制停止的特性(立刻释放所有monitors),可能会导致一系列难以处理的问题,故最新java版本stop方法已不可用,这里简单介绍下关于其替代方法interrupt()的使用。
如图:stop方法已无法再用,会直接抛出异常
stop被禁用
那么,interrupt()方法该怎么用呢?interrupt()其本身并不是一个强制打断线程的方法,其仅仅会修改线程的interrupt标志位,然后让线程自行去读标志位,自行判断是否需要中断。
先看第一个例子:
- 线程t1依次打印0到1000000
- 线程t2在等待1秒后,触发线程的t1.interrupt();
结合前面的说明,可以先想一下log输出是什么?
调用结果
自然地,t1.interrupt()并没有起到效果,t1线程照样还是打印完了0~1000000
按前文所说,是否需要真正中断,需要让当事线程自行处理,如图:
自行处理
如果线程t1发现自己被要求中断了,则直接退出run()方法,结果如下:
自行处理结果
一般的,我们会在执行耗时操作前去做isInterrupted()的判断,比如说IO、网络之类的,避免多余的操作。
其实到这里,也顺便说明的下对象里的wait()和线程里的sleep()方法,为什么总是和InterruptedException扯到一起?在设计里,如果线程处于休眠状态,那一旦其被调用interrupt()方法,则就没有必要继续休眠下去了,直接抛出异常InterruptedException,让被打断线程去做收尾操作,及时释放线程资源。
如图示例:
image.png总结:interrupt()是一个“很软”的操作,也就是提醒线程应该结束了,至于如何结束,什么时候结束,以及是否需要结束,都是由线程自行处理。所以,interrupt()的使用,会让开发做更多的事,但这是有必要的,因为只有线程自己,才知道如何合适的结束自己。