我試圖理解程序中發生了什麼,我有異常「消失」,沒有任何通知(和一個線程停止工作)。未捕獲的異常如何在線程中表現?
我可以拿出來重現問題最簡單的情況是這樣的:
(defn -main []
(let [a (future (do (println "Ouch... ")
(/ 0 0)
(println "We never arrive here")))]
(Thread/sleep 1000)
(println "Hmmmm" @a)))
毫無疑問的是,當在REPL運行(或使用雷音運行),我得到一個異常:
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>
所以在執行未來的(否則「哎喲......」止跌」 )然後拋出一個異常(否則「我們永遠不會到達這裏」會打印)......但是這個異常無處可尋,程序繼續,好像一切都很好。
顯然只要我不試圖解引用未來,線程可以靜靜地死掉,在它的工作中(在這種情況下打印到標準輸出),並且無處可尋。
這是正常的嗎?
我是否應該在Emacs/cider緩衝區之一中找到該異常的(堆棧)跟蹤?
如果將來有工作(例如,從隊列中消費消息)並在出現問題時「發出警告」,這會是一種慣用的方式嗎?
我應該在try/catch塊內包裝每一個未來的調用嗎?
我應該設置一個默認的未捕獲異常處理程序嗎?
我不應該使用未來運行「不停止」線程嗎?
基本上我在Java/Clojure的,這裏的行爲很迷茫,想有兩種解釋,爲什麼它的表現如何,我應該處理這個問題,這種方式和。
小點,但Clojure未來*是*未來,而不是包裝。 –
改進了更具體的答案 – Kevin