基本上我有以下代码段,
(let [task (FutureTask. fn)
thr (Thread. task)]
(.start thr)
;;wait for signal...
(.cancel task true)
(.stop thr))
问题是偶尔取消不起作用,AFAICT取消原因和异常被抛出但是线下的一些代码捕获了它?是否有可靠的方法取消未来的任务?
fn是一个基本上执行一系列长时间运行计算的函数,因此我无法循环检查布尔标志。
答案 0 :(得分:6)
没有办法在Java中自动停止正在运行的任务 - 在一般情况下,简单地“杀死”正在执行的线程是不安全的,因为这样做会使事情处于不一致状态。结果,这种能力被故意遗漏了Java。
取消任务时,会在执行的线程中设置一个标志,但不会抛出任何异常。为了允许取消任务,您必须编写代码以定期检查线程是否已被中断:
while (notDone) {
if (Thread.isInterrupted()){
return; // we were cancelled (or interrupted in some other way)
}
doSomeHardWork()
}
答案 1 :(得分:1)
根据我(有限)的知识,没有通用的方法可以做到这一点。这是因为你可以有一个不间断的远程任务,你可以有一个任务是纯函数,因此可以安全杀死,你可以有很多子任务(如提到的nerdytenor - 检查每个之间的isInterrupted状态),你可以混合使用一切,你可以有任务,当被杀死时会把其他任务置于全局锁定状态......所以据我所知你必须自己做。
你做了什么样的计算?你能在里面做什么吗?也许创建一些全局的,线程安全的表toInterrupt并检查每个子任务是否要取消整个任务?我知道这是非常非惯用,但现在想不出更好的事情。
或者,如果这些是真正的纯函数计算,并且你确实很确定 - 杀死进程/线程并希望你是对的。
答案 2 :(得分:0)
这个问题可能与Executing a function with a timeout
有关宏适用于我的代码,thunk-timeout代码为here
(defmacro with-timeout [time & body]
`(thunk-timeout (fn [] ~@body) ~time))