【发布时间】:2017-02-15 00:50:25
【问题描述】:
我正在开发一个小游戏(Java,LibGdx),玩家在其中使用预定义的代码行填充完形填空样式的函数。然后,游戏将编译代码并运行一个小型测试套件,以验证该函数是否完成了它应该做的事情。
编译和运行代码已经可以了,但是我遇到了检测无限循环的问题。考虑以下函数:
// should compute the sum of [1 .. n]
public int foo(int n) {
int i = 0;
while (n > 0) {
i += n;
// this is the place where the player inserts one of many predefined lines of code
// the right one would be: n--;
// but the player could also insert something silly like: i++;
}
return i;
}
请注意,实际使用的函数可能更复杂,一般无法确保不会出现无限循环。
目前我正在使用ExecutorService 在线程中运行小型测试套件(为每个函数提供),设置超时以中止等待以防线程卡住。这样做的问题是,陷入无限循环的线程将永远在后台运行,这当然会在某些时候对游戏性能产生相当大的影响。
// TestClass is the compiled class containing the function above and the corresponding test suite
Callable<Boolean> task = new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
// call the test suite
return new TestClass().test();
}
};
Future<Boolean> future = executorService.submit(task);
try {
Boolean result = future.get(100, TimeUnit.MILLISECONDS);
System.out.println("result: " + (result == null ? "null" : result.toString()));
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
future.cancel(true);
}
我现在的问题是:如何优雅地结束在无限循环中意外旋转的线程?
*编辑为了澄清为什么在这种情况下,防止无限循环是不可能/可行的:函数、它们的测试套件和填补空白的行是从磁盘加载的。将有数百个函数可以插入至少两行代码。玩家可以将任何线拖入任何间隙。确保函数间隙/代码行的组合不会产生无限循环甚至运行时间超过超时所需的工作随着函数的数量呈指数增长。这很快就到了没有人有时间手动检查所有这些组合的地步。此外,一般来说,由于停机问题,要确定一个函数是否会及时完成几乎是不可能的。
【问题讨论】:
标签: java multithreading loops