Java8Stream異常處理
問題描述
我也是剛用上Java8的Stream,所有的一切都還在照貓畫虎的階段。
在異常處理這塊不敢貿然前進,因為我看到某篇文的這樣一段話
在單線程環境中,使用捕獲受檢異常并重新拋出非受檢異常的方法是可行的。但是在多線程環境這樣用,就存在一些風險。
多線程環境中,Lambda表達式中發生的錯誤會被自動傳遞到主線程中。這會帶來兩個問題:
這不會停止其他正在并行執行的Lambda表達式。如果有多個線程拋出了異常,在主線程中卻只能捕獲到一個線程中的異常。如果這些異常信息都很重要的話,那么更好的方法是在Lambda表達式中就進行異常處理并將異常信息作為結果的一部分返回到主線程中。
我現在是用的Stream流的Map方法,當然用的是并發,想在map里的方法里只要有一個出錯就讓他停下來,不運行其他的。。這個需求該怎么搞。。
paths.stream() .map(path -> {try { return new File(path).getCanonicalPath();} catch(IOException ex) { throw new RuntimeException(ex);} }) .forEach(System.out::println);
我用了這種方法確實停下來了,那還有什么好的方法,或者說是否有何問題,這樣的話就拿不到具體哪個線程有問題了吧
問題解答
回答1:你的思維模式就不對,map filter 這類不是語法糖, java8還是有函數式編程能力的。函數式的核心是不變性,這里不是要求取消變量,而是要建立一種等價思維,以求值 > 過程的方式去思考問題。
你的例子,比如要求在map中停下來這就在設計之外,因為map的語意保證了它一定會遍歷完所有數據,返回的類型一定一致,而且長度相同。同樣貿然拋出rumtime exception也是非常的不優雅。
有幾個方案,使用optional或者either(這個官方不提供,需要自己弄一個)來包裝你的返回類型來保證map語義(把錯誤放到返回值里去,但是類型不變,具體可以百度)
如果你的數據有前后關系,使用fold(reduce)來處理而不是map。
不使用stream而用回for break,編程其實就是編程,關鍵是解決問題,針對問題來選擇最好的方案,有的時候steam方案不如傳統的for,fork/join也不如手工sync notify。
另,stream的并行其實沒有你想的那么好,濫用了copyonwrite,我自己玩過一陣之后幾乎再也不用了。不過 java8有個completableFuture估計能滿足你的要求。
回答2:CountDownLatch(1)
catch異常時:
CountDownLatch.countDown();
最后:
CountDownLatch.await();xxx.stop();
Java8的Stream沒用過了。。。
相關文章:
1. mysql在限制條件下篩選某列數據相同的值2. mysql 獲取時間函數unix_timestamp 問題?3. javascript - 按鈕鏈接到另一個網址 怎么通過百度統計計算按鈕的點擊數量4. java - Mybatis 數據庫多表關聯分頁的問題5. 新入手layuiadmin,部署到tp中。想用php自已寫一個后臺管理系統。6. 急急急!!!求大神解答網站評論問題,有大神幫幫小弟嗎7. php - 生產環境下,給MySQL添加索引,修改表結構操作,如何才能讓線上業務不受影響?8. mysql - Sql union 操作9. mysql - 僅僅只是把單引號與反斜杠轉義不用prepare statement能否避免sql注入?10. android - 安卓做前端,PHP做后臺服務器 有什么需要注意的?
