今天流行的Java宗教严重禁止在stop()
[1] [2] [3]上使用Thread
实例方法。它在official documentation中标记为已弃用,并带有以下内容开头的消息:
这种方法本质上是不安全的。使用
Thread.stop
停止某个线程会导致它解锁所有已锁定的监视器(这是未经检查的ThreadDeath
异常向上传播的自然结果)。如果先前受这些监视器保护的任何对象处于不一致状态,则受损对象对其他线程可见,可能导致任意行为。 [...]
甚至还提供了whole article更详细的信息。 (特别是当ThreadDeath
到达顶峰时它是沉默的,即使你防范它,你无论如何都无法防范Thread.stop(Throwable t)
。)
总的来说,我同意文章所担心的内容,以及related question on StackOverflow的答案 - 在世界上几乎所有的用例中都有比stop()
更好的方法。但不是所有。
这是一个用例,我正在努力想出一个更好的方法。我邀请你的建议。
我正在使用在Java之上运行的交互式控制台,它允许用户以交互式解释方式运行任意Java语句和调用Java的Python函数。 (有关屏幕截图,请参阅Jython console。)
现在,用户可以编写任意函数。他们中的一些人可能会调用Java方法,导致无限循环打印大量输出,几乎使系统饱和,因此响应变得非常缓慢。
当用户像这样搞砸时,我需要让他们有机会杀死线程(使用按钮),并打捞他们在会话中产生的剩余工作和存储在局部变量中。
如果在线程上调用interrupt()
失败,(例如,如果它在陷入无限循环时从未进入等待状态),那么我们可以看到两个选项:(1)杀死应用程序直接或(2)在坏线程上使用stop()
,并让用户挽救尚未损坏的任何内容。
是的我知道有些物品可能已损坏且无法正常工作。但我们正在谈论打捞任何可能留在有效状态的东西(除了一两件事之外,这几乎可能是一切)。
有人可以看到这个推理有任何问题吗?如果这是一个有效的用例,那么它是否意味着该方法不应该被弃用:)?
答案 0 :(得分:0)
调用Thread.stop()
是一个坏主意。故事结束。
它可能在实践中起作用,但是您在此过程中牺牲了大多数JVM的并发保证。您的整个程序本质上是运行未定义的行为。它不仅仅是线程中的线程或数据可能会被破坏,而是当线程被杀死时JVM的任何部分恰好处于易受攻击的状态。
听起来你正在寻找某人确认你的用例以某种方式避免了JVM的风险。它没有,所以你不太可能得到这样的确认。如果你没有看到问题对你有更多的权力,但是当它以无法解释或危险的方式失败时不要感到惊讶。
正如Peter Lawrey建议你应该在一个孤立的JVM中运行这个不受信任的代码,操作系统的进程管理可以支持杀死资源占用进程。如果你不能这样做,因为你传递奇怪的资源,如打开文件描述符,是你的问题。