我们举办了一场AI
编程竞赛,参赛者将使用我们提供的AI
编写在JVM
上运行的API
。我们通过限制它们可以使用SecurityManager
做的事情,将它们放到沙箱中,在运行时,它们只需设置几个标志,这些标志就是它们的决定。我们的系统和他们的AI
之间唯一的交互是通过这些标志,所以如果他们的线程突然死亡,对我们没有不良影响。
当AI
的计算时间太长时,我们会关闭它们的线程。然而,我们无法找到一种方法来保证我们会销毁他们的线程。一个可能的原因是AI
进入了无限循环,没有阻塞,使得Thread.interrupt()
无用。Thread.stop()
是不可靠的,因为如果它们在try catch块中,ThreadDeath
异常将被捕获,并且对我们来说没有问题,因为它们不会接触任何不好的东西,我们也不关心它们是否会死。
目前我们只是忽略它们的线程,并在它们超时后继续运行,但它们的无限循环将在后台继续处理,直到JVM
死亡。这对我们来说是不可接受的,因为我们将在web服务器上全天候在后台运行比赛,所以我们想要尽可能多的稳定性。一种想法是在单独的JVM
中运行每个游戏,但这比我们想要的要复杂得多。
有没有任何可靠的方法来销毁线程?
发布于 2012-05-28 23:06:38
在尝试了几种方法后,我们得出的结论是,没有保证的解决方案。通过在线程上调用stop(),该线程能够捕获ThreadDeath可抛出对象并将其完全忽略。因此,如果它在while循环中不断地捕获它,或者如果它递归地调用一个捕获它的方法,就不能保证您可以杀死它。
由于我们无法控制在这种情况下将运行的代码,并且这些代码不一定是用Java编写的(我们也支持Jython),因此我们能想到的最佳解决方案是生成一个线程,该线程进入一个循环,该循环不断地调用suspend(),然后在该线程上执行stop()。结果在大多数情况下都有效,但偶尔无法杀死恶意线程。
发布于 2012-02-03 06:25:32
为他们提供一个他们必须定期调用的方法,即使在计算过程中也是如此。如果你判断它们“死了”,让这个方法永远休眠。显然,如果他们真的死了,他就不会工作,但你应该抓住大多数问题。
发布于 2012-02-03 06:39:05
http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#stop%28java.lang.Throwable%29
传入一个他们不知道的Throwable的自定义子类,您可以用regex:/catch\s*(\s*Throwable/
检查他们的代码,以确保他们不会在任何地方捕获Throwable。
https://stackoverflow.com/questions/9118715
复制相似问题