Exception 未捕获异常在线程中的行为如何?
我正在试图理解一个程序发生了什么,在这个程序中,我的异常在没有任何通知的情况下“消失”(线程停止工作) 我能想出的重现这个问题的最简单的例子是:Exception 未捕获异常在线程中的行为如何?,exception,exception-handling,clojure,future,Exception,Exception Handling,Clojure,Future,我正在试图理解一个程序发生了什么,在这个程序中,我的异常在没有任何通知的情况下“消失”(线程停止工作) 我能想出的重现这个问题的最简单的例子是: (defn -main [] (let [a (future (do (println "Ouch... ") (/ 0 0) (println "We never arrive here")))] (Thread/sleep 1000)
(defn -main []
(let [a (future (do (println "Ouch... ")
(/ 0 0)
(println "We never arrive here")))]
(Thread/sleep 1000)
(println "Hmmmm" @a)))
毫无疑问,在repl上运行(或使用lein run)时,我会遇到一个异常:
so.core> (-main)
Ouch...
ArithmeticException Divide by zero clojure.lang.Numbers.divide (Numbers.java:156)
这是我所期望的行为
但是现在,如果我删除对未来的取消引用:
(defn -main []
(let [a (future (do (println "Ouch... ")
(/ 0 0)
(println "We never arrive here")))]
(Thread/sleep 1000)
(println "Hmmmm")))
以下是输出:
so.core> (-main)
Ouch...
Hmmmm
nil
so.core>
因此,未来将被执行(否则“哎哟…”将不会被打印),然后显然会抛出一个异常(否则“我们永远不会到达这里”将被打印)。。。但这一例外却无处可寻,该计划继续进行,似乎一切都很好
显然,只要我不试图取消对未来的引用,线程就可以悄无声息地死去,在其工作的中间(在这种情况下,打印到STDUT),并且异常没有找到。
这正常吗
我应该在我的一个Emacs/cider缓冲区中找到该异常的(堆栈)跟踪吗
什么是一种惯用的方式让future完成它的工作(例如,使用队列中的消息),并且在出现问题时“警告”我
我是否应该将未来的每一个调用都封装在try/catch块中
我应该设置默认的未捕获异常处理程序吗
我不应该使用future运行“不停止”线程吗
基本上,我对这里的Java/Clojure的行为感到非常困惑,我想解释一下它为什么会这样,以及我应该如何处理这个问题。在Clojure
future
中,是一个生成具体化的Java.util.concurrent.future
的宏,取消引用它会调用该方法。该方法可以抛出表示线程中未捕获异常的。因此,如果不取消引用,就不会调用.get
,也不会得到异常
clojure文档站点有源代码,因此您可以看到实际的实现
如果您不想取消引用,我想您应该
尝试/在线程中捕获,并以您选择的任何方式进行处理。这点很小,但Clojure future是一个未来,而不是包装器。改进了答案,使其更加具体