FutureTask cancel()

时间:2011-08-07 00:48:06

标签: java clojure futuretask

基本上我有以下代码段,


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

问题是偶尔取消不起作用,AFAICT取消原因和异常被抛出但是线下的一些代码捕获了它?是否有可靠的方法取消未来的任务?

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

3 个答案:

答案 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))