为什么不能用stop停止线程

为什么废弃stop()?

java里线程停止有一个方法,叫stop(),但是很早就被废弃了,因为会导致很多问题。比如下面一种case:

假设这样一种情况,有三个线程,分别为Thread1,Thread2,Thread3。
此时Thread1暂停,但是仍然持有内存锁,Thread1是否被恢复也不知道,而Thread3想要读取内存,只能等待,如果此时Thread1等待了Thread3的锁,那就会变成死锁了,这也是一个严重的问题。

如果此时情况变化了,Thread1被停止,立即释放内存锁,Thread3会立即获得锁,内存根本没有清理的机会(原来Thread1数据写一半,突然被干掉了,内存还没有被清理干净),就被Thread3读取了,而Thread3读到的也是一个莫名其妙的数据。

应该如何停止线程?

我们目的是让线程里的任务结束,任务结束,线程会自动停止,并处理自己的烂摊子,如果强制stop的话,谁处理烂摊子?

  • 通知目标线程自行结束,而不是强行停止
  • 目标线程应当具备处理终端的能力
  • 中断方式:Interrupt 和 boolean 标志位

interrupt方式

1、原生支持的情况,如果调用sleep()方法,会要求加上try-catch,来捕获中断异常。

如果调用interrupt() 会走到异常位置,在捕获异常出可以进行处理终止线程,但是有些情况并不支持原生的interrupt,例如:

此时调用interrupt() ,而线程没有任何感觉,那么怎么办呢?

用interrupted()来进行判断,是否发生了中断。

interrupted() 与 isInterrupted()区别:

  • interrupted() 是静态方法
  • 获取的是当前运行的线程
  • 中断状态调用后清空,重复调用后续返回false

  • isInterrupted() 是非静态方法
  • 调用的是线程对象对应的线程
  • 可重复调用,中断清空前一直返回true

我们看下底层源码,调用的是c++的程序

首先是找到的对象不一样,其次分别调用的是Interrupted()和isInterrupted()

不同的就是多了一行代码,清空当前的中断状态。具体状态值是被加了锁,保证读的时候是线程安全的。

Boolean标注位

这个比较简单了,用一个标志位,此时注意的是,为了保证线程间内存可见性的问题,需要加上volatile来修饰

最后总结一下,interrupt与Boolean本质上是一致的,都是一个标志位,只不过interrupt对标志位加了锁,并且用的是jni方式,因此使用interrupt会对性能有一点点影响。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容