为什么不要用stop方法停止线程?

线程启动完毕后,在运行时可能需要终止,Java提供的终止方法只有一个stop,但是我不建议使用这个方法,因为它有以下三个问题:(1)stop方法是过时的从Java编码规则来说,已经过时的方法不建议采用。(2)stop方法会导致代码逻辑不完整stop方法是一种“恶意”的中断,一旦执行stop方法,即终止当前正在运行的线程,不管线程逻辑是否完整,这是非常危险的。看如下的代码:

为什么不要用stop方法停止线程?

这段代码的逻辑是这样的:子线程是一个匿名内部类,它的run方法在执行时会休眠1秒钟,然后再执行后续的逻辑,而主线程则是休眠0.1秒后终止子线程的运行,也就是说,JVM在执行thread.stop()时,子线程还在执行sleep(1000),此时stop方法会清除栈内信息,结束该线程,这也就导致了run方法的逻辑不完整,输出语句println代表的是一段逻辑,可能非常重要,比如子线程的主逻辑、资源回收、情景初始化等,但是因为stop线程了,这些就都不再执行,于是就产生了业务逻辑不完整的情况。这是极度危险的,因为我们不知道子线程会在什么时候被终止,stop连基本的逻辑完整性都无法保证。而且此种操作也是非常隐蔽的,子线程执行到何处会被关闭很难定位,这为以后的维护带来了很多麻烦。(3)stop方法会破坏原子逻辑多线程为了解决共享资源抢占的问题,使用了锁概念,避免资源不同步,但是正因此原因,stop方法却会带来更大的麻烦:它会丢弃所有的锁,导致原子逻辑受损。例如有这样一段程序:

为什么不要用stop方法停止线程?

MultiThread实现了Runnable接口,具备多线程能力,其中run方法中加上了synchronized代码块,表示内部是原子逻辑,它会先自增然后再自减少,按照synchronized同步代码块的规则来处理,此时无论启动多少个线程,打印出来的结果都应该是a=0,但是如果有一个正在执行的线程被stop,就会破坏这种原子逻辑,代码如下:

为什么不要用stop方法停止线程?

首先要说明的是所有线程共享了一个MultiThread的实例变量t,其次由于在run方法中加入了同步代码块,所以只能有一个线程进入到synchronized块中。此段代码的执行顺序如下:1)线程t1启动,并执行run方法,由于没有其他线程持同步代码块的锁,所以t1线程执行自加后执行到sleep方法即开始休眠,此时a=1。2)JVM又启动了5个线程,也同时运行run方法,由于synchronized关键字的阻塞作用,这5个线程不能执行自增和自减操作,等待t1线程锁释放。3)主线程执行了t1.stop方法,终止了t1线程,注意,由于a变量是所有线程共享的,所以其他5个线程获得的a变量也是1。4)其他5个线程依次获得CPU执行机会,打印出a值。分析了这么多,相信读者也明白了输出的结果,结果如下:

为什么不要用stop方法停止线程?

原本期望synchronized同步代码块中的逻辑都是原子逻辑,不受外界线程的干扰,但是结果却出现原子逻辑被破坏的情况,这也是stop方法被废弃的一个重要原因:破坏了原子逻辑。既然终止一个线程不能使用stop方法,那怎样才能终止一个正在运行的线程呢?答案也很简单,使用自定义的标志位决定线程的执行情况,代码如下:

为什么不要用stop方法停止线程?

这是很简单的办法,在线程体中判断是否需要停止运行,即可保证线程体的逻辑完整性,而且也不会破坏原子逻辑。可能有读者对Java API比较熟悉,于是提出疑问:Thread不是还提供了interrupt中断线程的方法吗?这个方法可不是过时方法,那可以使用吗?它可以终止一个线程吗?非常好的问题,interrupt,名字看上去很像是终止一个线程的方法,但是我可以很明确地告诉你,它不是,它不能终止一个正在执行着的线程,它只是修改中断标志而已,例如下面一段代码:

执行这段代码,你会发现一直有Running在输出,永远不会停止,似乎执行了interrupt没有任何变化,那是因为interrupt方法不能终止一个线程状态,它只会改变中断标志位(如果在t1.interrupt()前后输出t1.isInterrupted()则会发现分别输出了false和true),如果需要终止该线程,还需要自行进行判断,例如我们可以使用interrupt编写出更加简洁、安全的终止线程代码

总之,如果期望终止一个正在运行的线程,则不能使用已经过时的stop方法,需要自行编码实现,如此即可保证原子逻辑不被破坏,代码逻辑不会出现异常。当然,如果我们使用的是线程池(比如ThreadPoolExecutor类),那么可以通过shutdown方法逐步关闭池中的线程,它采用的是比较温和、安全的关闭线程方法,完全不会产生类似stop方法的弊端。

原创文章,作者:小技术君,如若转载,请注明出处:https://www.sudun.com/ask/34032.html

(0)
小技术君's avatar小技术君
上一篇 2024年4月3日 下午12:15
下一篇 2024年4月3日 下午12:17

相关推荐

  • 我们世界中的10个算法

    下面的图表展示了我们日常生活中最常用的算法。它们被应用在互联网搜索引擎、社交网络、WiFi、手机甚至卫星等各个领域。 1.排序算法 排序算法用于将一组数据按照特定的顺序进行排列。它…

    CDN资讯 2024年4月18日
    0
  • DNS_ PROBE_ FINISHED_NO_INTERNET

    最近公司的电脑老是用着用着就会无法打开网页,在下面就会提示:DNS_ PROBE_ FINISHED_NO_INTERNET。从提示来看就是DNS有问题。 排查过程 我们点击上方的…

    2024年6月2日
    0
  • 关于TCP的所有你想知道的

    连接导向、可靠和比特流导向 在网络层的IP协议是不可靠的。它负责将数据包从一个IP地址传递到另一个IP地址,但不对传递的数据包的交付、顺序或完整性做任何保证。这就是TCP发挥作用的…

    2024年4月15日
    0
  • 为什么CDN可以加速

    内容分发网络(CDN)是一种通过在全球范围内部署服务器来缓存和提供网络内容的技术。CDN的主要目的是加速网站的访问速度,减少延迟和提高用户体验。下面将解释为什么CDN可以实现加速效…

    2024年3月16日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注