如何杀死不可中断的线程?

时间:2012-02-02 19:32:39

标签: java multithreading jvm

我们开展了AI计划竞赛,参赛者将使用我们提供的AIJVM上运行的API进行编码。我们通过限制它们可以用SecurityManager做什么来将它们放入沙盒中,并且在运行时它们只是设置了几个标志,这是他们的决定。我们的系统和它们AI之间唯一的交互是通过这些标志,所以如果它们的线程突然死亡,对我们没有任何不良影响。

AI计算时间太长时,我们想关闭他们的线程。但是,我们无法找到保证我们将销毁其线程的方法。一个可能的原因是AI进入无限循环而没有阻塞,使得Thread.interrupt()无用。 Thread.stop()是不可靠的,因为如果它们处于try catch块中,ThreadDeath异常将被捕获,并且对我们没有任何问题,因为它们没有触及任何坏事,我们不关心它们是否会死

目前我们只是忽略他们的线程,并在超时后继续使用它们,但是它们的无限循环将在后台继续处理,直到JVM死掉。这对我们来说是不可接受的,因为我们将在24/7的Web服务器上在后台运行匹配,因此我们希望尽可能多的稳定性。一种想法是在一个单独的JVM中运行每个游戏,但这比我们想要的要复杂得多。

有没有确定的消防方法来破坏线程?

4 个答案:

答案 0 :(得分:0)

为他们提供他们必须定期调用的方法,即使在计算过程中也是如此。如果你判断他们已经“死了”,那么这个方法就会永远睡不着。显然,如果他们真的死了,他就行不通,但你应该抓住大多数问题。

答案 1 :(得分:0)

http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#stop%28java.lang.Throwable%29

传入他们无法了解的Throwable自定义子类,并且可以使用正则表达式检查他们的代码:/catch\s*(\s*Throwable/以确保它们不会在任何地方捕获Throwable。

答案 2 :(得分:0)

通常,不,您不应该停止JVM中的任意线程(因此不推荐使用这些方法)。问题的根源在于,当你杀死线程时,你不知道线程在系统中的哪个位置。在最糟糕的情况下,它可能位于JVM基础结构内部的同步块的中间,该块未准备好抛出意外异常。 (几乎不可能编写可以在任意点被异常杀死的强健同步代码。)

有关详细信息,请参阅此问题的高评价答案: Are java app servers able to destroy threads? If yes, how?

您可以通过合作设计逃脱,要求AI线程退出。如果确实如此,那么你很好。如果没有,则需要重新启动JVM。

答案 3 :(得分:0)

在尝试了几件事后,我们得出的结论是没有保证的解决方案。通过在线程上调用stop(),该线程能够捕获ThreadDeath throwable并完全忽略它。因此,如果它在while循环中连续捕获它,或者如果它以递归方式调用捕获它的方法,则不能保证你可以杀死它。

由于我们没有对在这种情况下运行的代码有任何控制,并且该代码不一定是Java(我们也支持Jython),我们可以提出的最佳解决方案是生成一个线程进入一个连续调用suspend()然后在线程上停止()的循环。结果适用于大多数情况,但有时无法杀死恶意线程。