stream流引發的問題


    
     SearchHit[] searchHits1 = searchHits.get();

     //方式一
for (int i = 0; i < searchHits1.length; i++) {
Map<String, Object> source = searchHits1[i].getSource();
list.add(source);
}
     //方式二
if (searchHits.isPresent()) {
Arrays.asList(searchHits.get()).parallelStream().forEach(InternalSearchHit -> list.add(InternalSearchHit.getSource()));
}

代碼的邏輯是從es庫中查出指定的數據,然后存放到list集合中,返回頁面或者進行其他處理;這里遇到的問題就是,在方式二操作的時候,list中會出現空數據,如下圖:

 

 

存在空數據的情況,所以就會造成各種想不到的bug,唉,頭疼啊;

換成方式一顯示正常;

為啥?

究其原因:我仔細找找。。。

找到了,是流的原因,換成以下代碼,就可以了:

        if (searchHits.isPresent()) {
            Arrays.asList(searchHits.get()).stream().forEach(InternalSearchHit -> list.add(InternalSearchHit.getSource()));
        }

 

這里就要說說流的區別了:

stream()和parallelStream()的區別:簡單的說就是一個是單管道,另個一個是多管道;因為是多管道,就會涉及到線程安全問題;遍歷耗時前者是后者的將近一半

引用看到的一篇文章部分內容:https://blog.csdn.net/zhao1299002788/article/details/85004434

在使用stream.foreach時這個遍歷沒有線程安全問題,但是使用parallelStream就會有線程安全問題,所有在parallelStream里面使用的外部變量,比如集合一定要

使用線程安全集合,不然就會引發多線程安全問題。在並行時,實際上是多個線程執行,這個時候還有個問題,就是當你在遍歷中使用例如請求里面的數據時,就

會報一個異常,這個異常就是多個線程執行,但是其他線程沒有這個請求的數據,所以獲取不到。這時解決辦法是把需要的數據在遍歷外面取到,再傳遞進去就可

以解決。
或者說,是外部的list不是線程安全的,導致了parallelStream()線不安全;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM