2

基本上我有以下片段,


(let [task (FutureTask. fn)
      thr (Thread. task)]
  (.start thr)
  ;;wait for signal...
  (.cancel task true)
  (.stop thr))

问题是偶尔取消不起作用,AFAICT 取消导致并引发异常,但是下面的一些代码捕获了它?有没有确定的方法可以取消未来的任务?

fn 是一个基本上执行一系列长时间运行计算的函数,因此我无法循环检查布尔标志。

4

3 回答 3

6

在 Java 中没有办法自动停止正在运行的任务——在一般情况下,简单地“杀死”正在执行的线程是不安全的,因为这样做可能会使事情处于不一致的状态。结果,这种能力被有意地排除在 Java 之外。

当您取消任务时,在执行线程中会设置一个标志,但不会引发异常。为了允许取消任务,您必须编写代码来定期检查线程是否已被中断:

while (notDone) {
    if (Thread.isInterrupted()){
      return; // we were cancelled (or interrupted in some other way)
    }

    doSomeHardWork()
}
于 2011-08-07T03:50:42.603 回答
1

根据我的(有限的)知识,没有通用的方法可以做到这一点。这是因为你可以有一个不可中断的远程任务,你可以有一个纯函数任务,因此可以安全地杀死,你可以有很多子任务(正如 nerdytenor 提到的——检查每个之间的 isInterrupted 状态),你可以混合一切,你可以有一个任务,当被杀死时会将其他任务置于全局锁定状态......所以据我所知,你必须自己做。

你执行什么样的计算?你能在里面做什么吗?如果整个任务即将被取消,也许创建一些全局的、线程安全的表 toInterrupt 并检查每个子任务?我知道这是非常不习惯的,但现在想不出更好的方法。

或者,如果这些确实是纯函数计算并且您对此非常确定——杀死进程/线程并希望您是对的。

于 2011-08-10T14:58:27.263 回答
0

这个问题可能与Executing a function with a timeout有关

该宏适用于我的代码,thunk-timeout 代码在这里

(defmacro with-timeout [time & body]
  `(thunk-timeout (fn [] ~@body) ~time))
于 2013-10-03T09:15:01.877 回答