Java8Stream異常處理
問題描述
我也是剛用上Java8的Stream,所有的一切都還在照貓畫虎的階段。
在異常處理這塊不敢貿(mào)然前進(jìn),因為我看到某篇文的這樣一段話
在單線程環(huán)境中,使用捕獲受檢異常并重新拋出非受檢異常的方法是可行的。但是在多線程環(huán)境這樣用,就存在一些風(fēng)險。
多線程環(huán)境中,Lambda表達(dá)式中發(fā)生的錯誤會被自動傳遞到主線程中。這會帶來兩個問題:
這不會停止其他正在并行執(zhí)行的Lambda表達(dá)式。如果有多個線程拋出了異常,在主線程中卻只能捕獲到一個線程中的異常。如果這些異常信息都很重要的話,那么更好的方法是在Lambda表達(dá)式中就進(jìn)行異常處理并將異常信息作為結(jié)果的一部分返回到主線程中。
我現(xiàn)在是用的Stream流的Map方法,當(dāng)然用的是并發(fā),想在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還是有函數(shù)式編程能力的。函數(shù)式的核心是不變性,這里不是要求取消變量,而是要建立一種等價思維,以求值 > 過程的方式去思考問題。
你的例子,比如要求在map中停下來這就在設(shè)計之外,因為map的語意保證了它一定會遍歷完所有數(shù)據(jù),返回的類型一定一致,而且長度相同。同樣貿(mào)然拋出rumtime exception也是非常的不優(yōu)雅。
有幾個方案,使用optional或者either(這個官方不提供,需要自己弄一個)來包裝你的返回類型來保證map語義(把錯誤放到返回值里去,但是類型不變,具體可以百度)
如果你的數(shù)據(jù)有前后關(guān)系,使用fold(reduce)來處理而不是map。
不使用stream而用回for break,編程其實就是編程,關(guān)鍵是解決問題,針對問題來選擇最好的方案,有的時候steam方案不如傳統(tǒng)的for,fork/join也不如手工sync notify。
另,stream的并行其實沒有你想的那么好,濫用了copyonwrite,我自己玩過一陣之后幾乎再也不用了。不過 java8有個completableFuture估計能滿足你的要求。
回答2:CountDownLatch(1)
catch異常時:
CountDownLatch.countDown();
最后:
CountDownLatch.await();xxx.stop();
Java8的Stream沒用過了。。。
相關(guān)文章:
1. 淺談vue生命周期共有幾個階段?分別是什么?2. macos - mac下docker如何設(shè)置代理3. node.js - Angular-webpack-Starter, 怎么把NodeJS添加進(jìn)項目里?4. html5 - vue項目中我用webpack編譯不成功5. javascript - 安裝了babel,不起作用6. html5 - 純CSS怎么做出這種一模一樣的導(dǎo)航條導(dǎo)航塊那里還有個下拉菜單,請大家指導(dǎo)一下7. index.php錯誤,求指點8. 微信公眾號在線生成二維碼帶參數(shù)怎么搞?9. 微信開放平臺 - android 微信支付后點完成按鈕,后回調(diào)打開第三方頁面,屏幕閃動,求解決方法10. 視頻 - html5 video的autoplay 在智能手機上不運作?
