我们开展了AI
计划竞赛,参赛者将使用我们提供的AI
对JVM
上运行的API
进行编码。我们通过限制它们可以用SecurityManager
做什么来将它们放入沙盒中,并且在运行时它们只是设置了几个标志,这是他们的决定。我们的系统和它们AI
之间唯一的交互是通过这些标志,所以如果它们的线程突然死亡,对我们没有任何不良影响。
当AI
计算时间太长时,我们想关闭他们的线程。但是,我们无法找到保证我们将销毁其线程的方法。一个可能的原因是AI
进入无限循环而没有阻塞,使得Thread.interrupt()
无用。 Thread.stop()
是不可靠的,因为如果它们处于try catch块中,ThreadDeath
异常将被捕获,并且对我们没有任何问题,因为它们没有触及任何坏事,我们不关心它们是否会死
目前我们只是忽略他们的线程,并在超时后继续使用它们,但是它们的无限循环将在后台继续处理,直到JVM
死掉。这对我们来说是不可接受的,因为我们将在24/7的Web服务器上在后台运行匹配,因此我们希望尽可能多的稳定性。一种想法是在一个单独的JVM
中运行每个游戏,但这比我们想要的要复杂得多。
有没有确定的消防方法来破坏线程?
答案 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()然后在线程上停止()的循环。结果适用于大多数情况,但有时无法杀死恶意线程。