我用 Java 编写了一个数独求解器作为作业,目前我正在尝试找出它可能面临的有问题的输入,以使其变得更好。我已经生成了几千个数独网格David Bau 的数独生成器 http://davidbau.com/archives/2006/09/04/sudoku_generator.html,现在我正在针对他们运行我的程序。
问题是,虽然它们中的大多数在非常合理的时间内完成,但其中一些被证明是有问题的,并使我的算法搜索变得疯狂,直到我用完堆空间。所以我认为我应该将解决工作转移到辅助线程并超时运行。现在,我正在使用一个线程的线程“池”(以ExecutorService
)并且我正在提交Callable
到它。然后我尝试获取超时值:
Callable<Long> solveAndReturnTime = new Callable<Long>() { /* snip */ };
Future<Long> time = executor.submit(solveAndReturnTime);
try
{
long result = time.get(10, TimeUnit.SECONDS);
System.out.printf("%d millis\n", result);
}
catch (TimeoutException e)
{
System.err.println("timed out");
time.cancel(true);
}
我的问题显然是,人们不会简单地取消一项Future
in Java. Future<T>.cancel(boolean)
显然不会立即中断任务。因此,池被困在执行一项永不停息的任务中,并且后续的尝试会超时,因为它们永远没有机会运行。
向池中添加更多线程不是一个选择,因为我在有限的内核上运行,如果顽固地运行太多任务,合法任务将不公平地减慢。我也不希望频繁检查任务是否从我的主要算法中中止而产生开销。
我怎么能突然、无情、粗暴地终止一项任务呢?我愿意接受任何能让我在主线程上恢复的事情。
EDIT我的算法是完全顺序的,不使用全局对象,并且不包含锁。据我所知,如果随机取消任务,不会出现任何问题;即使是这样,它也不是生产代码。我已经准备好为此踏上危险而危险的一步了。
就像在任何其他语言中仁慈地终止线程的方法一样,不推荐使用或不推荐使用。因为这样的方法可能会导致死锁(被终止的线程不会释放它所持有的锁)。
问题的正确解决方案是进行额外检查Thread.currentThread ().isInterrupted ()
在 Callable 中主循环的每次迭代中。因此,当线程被中断时,它会看到它并优雅地关闭。
由于您的代码在另一个线程中运行,因此修改它应该不难。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)