如何正确的停止一个线程?

2018-11-15  本文已影响0人  Hoker_
实际项目中,有时候需要中断另外一个线程,早期可以使用stop()方法,但由于stop强制停止的特性(立刻释放所有monitors),可能会导致一系列难以处理的问题,故最新java版本stop方法已不可用,这里简单介绍下关于其替代方法interrupt()的使用。

如图:stop方法已无法再用,会直接抛出异常


stop被禁用

那么,interrupt()方法该怎么用呢?interrupt()其本身并不是一个强制打断线程的方法,其仅仅会修改线程的interrupt标志位,然后让线程自行去读标志位,自行判断是否需要中断。

先看第一个例子:

  1. 线程t1依次打印0到1000000
  2. 线程t2在等待1秒后,触发线程的t1.interrupt();
仅调用interrupt()

结合前面的说明,可以先想一下log输出是什么?


调用结果

自然地,t1.interrupt()并没有起到效果,t1线程照样还是打印完了0~1000000
按前文所说,是否需要真正中断,需要让当事线程自行处理,如图:


自行处理
如果线程t1发现自己被要求中断了,则直接退出run()方法,结果如下:
自行处理结果

一般的,我们会在执行耗时操作前去做isInterrupted()的判断,比如说IO、网络之类的,避免多余的操作。

其实到这里,也顺便说明的下对象里的wait()和线程里的sleep()方法,为什么总是和InterruptedException扯到一起?在设计里,如果线程处于休眠状态,那一旦其被调用interrupt()方法,则就没有必要继续休眠下去了,直接抛出异常InterruptedException,让被打断线程去做收尾操作,及时释放线程资源。

如图示例:

image.png

总结:interrupt()是一个“很软”的操作,也就是提醒线程应该结束了,至于如何结束,什么时候结束,以及是否需要结束,都是由线程自行处理。所以,interrupt()的使用,会让开发做更多的事,但这是有必要的,因为只有线程自己,才知道如何合适的结束自己。

上一篇下一篇

猜你喜欢

热点阅读