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()線不安全;