立即杀死正在运行的未来线程

gw0*_*gw0 6 future clojure cancellation

我正在使用

(def f 
   (future 
      (while (not (Thread/interrupted)) 
         (function-to-run))))

(Thread/sleep 100)
(future-cancel f)
Run Code Online (Sandbox Code Playgroud)

在指定的时间(100毫秒)后取消我的代码.
问题是,我需要取消已经运行的函数'function-to-run',重要的是它在100ms后真正停止执行该函数.
我可以以某种方式将中断的信号传播到函数中吗?
这个功能不是第三方,我自己写的.

Jos*_*osh 7

这里要注意的基本事项是:没有自己的合作,你无法安全地杀死一个线程.由于您是希望能够过早杀死的功能的所有者,因此允许该功能合作并优雅安全地死亡是有意义的.

(defn function-to-run
  []
  (while work-not-done
    (if-not (Thread/interrupted)
      ; ... do your work
      (throw (InterruptedException. "Function interrupted...")))))

(def t (Thread. (fn []
                  (try
                    (while true
                      (function-to-run))
                    (catch InterruptedException e
                      (println (.getMessage e)))))))
Run Code Online (Sandbox Code Playgroud)

开始线程

(.start t)
Run Code Online (Sandbox Code Playgroud)

打断它:

(.interrupt t)
Run Code Online (Sandbox Code Playgroud)

您的方法对于您的用例是不够的,因为while仅在控制流返回后才检查条件function-to-run,但您希望function-to-run在执行期间停止.这里的方法只是不同之处在于更频繁地检查条件,即每次通过循环function-to-run.请注意function-to-run,您可以返回一些指示错误的值,而不是抛出异常,只要主线程中的循环检查此值,您就不必涉及异常.

如果您function-to-run没有可以执行interrupted检查的循环,那么它可能正在执行一些阻塞I/O. 您可能无法中断此操作,但许多API将允许您指定操作的超时.在最坏的情况下,您仍然可以interrupted在呼叫周围的功能中执行间歇性检查.但底线仍然适用:你不能安全地强制停止执行在函数中运行的代码; 它应该合作控制.

注意:我在这里的原始答案涉及提供一个Thread.stop()使用java的例子(虽然强烈反对).根据评论中的反馈,我修改了上面的答案.

  • "线程/停止"在[javadoc]中用巨型生物危害/放射性/死亡标志注释(https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#stop() ).它不仅难以安全使用,而且*不可能*安全使用,您永远不应该使用它.弃用通知附有您应该做的事情的描述,而且确实是这里提出的问题的完美解决方案. (2认同)