欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

解決JDK8的ParallelStream遍歷無序的問題

 更新時間:2021年07月28日 10:44:22   作者:hzoboy  
這篇文章主要介紹了解決JDK8的ParallelStream遍歷無序的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

JDK8的ParallelStream遍歷無序

ParallelStream其實就是一個并行執(zhí)行的流

它通過默認的ForkJoinPool,可能提高你的多線程任務的速度.

Stream具有平行處理能力,處理的過程會分而治之,也就是將一個大任務切分成多個小任務,這表示每個任務都是一個操作,因此像以下的程式片段:

List    
       list = Arrays.asList(1, 2, 3, 4, 5);
list.parallelStream().forEach(out::println);

你得到的展示順序不一定會是1、2、3、4、5,而可能是任意的順序,就forEach()這個操作來講,如果平行處理時,希望最后順序是按照原來Stream的數據順序,那可以調用forEachOrdered()。

List    
       list = Arrays.asList(1, 2, 3, 4, 5);
list.parallelStream().forEachOrdered(out::println);

parallelStream進行遍歷的坑,以及如何進行避免異步操作中出現的問題

Java8 已經很久了,現在都已經Java12版本了.

我所在的上家公司,在寫代碼時候推薦使用lambad來進行操作遍歷集合

也就是像下面一樣

List<Integer> list = new ArrayList<>();
for (int j = 0; j < 1000; j++) {
list.add(j);
}
list.stream().forEach(value -> {
System.out.println(value);
});

這種效率其實和傳統(tǒng)上的使用foreach以及for循環(huán)遍歷效果差不多,因為點開forEach方法會發(fā)現內部其實使用的是下面的方法進行對集合遍歷的

內部其實使用的還是for進行遍歷,所以兩者相比較其實沒有什么效率的差異的,當然這也會由于每個公司編程習慣不一樣,有的人更喜歡傳統(tǒng)上的for進行遍歷

因為上面的遍歷方式不會對效率有什么提升, 所以由此還有一種方式就是

parallelStream()
List<Integer> list = new ArrayList<>();
for (int j = 0; j < 1000; j++) {
list.add(j);
}
list.parallelStream().forEach(value -> {
System.out.println(value);
});

上面的方法其實就是異步的,

這種遍歷方式因為是異步遍歷,會產生一種情況,就是遍歷的順序是無序的,當然也有相應的好處就是,遍歷速度會快,當對生成結果不考慮排序問題而且數據量比較大的時候可以使用.

但是,有利自然有弊,因為異步的所以需要考慮線程的問題,就是生成的結果真的是你想要的么?

以下面的例子來運行一段代碼:

public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int j = 0; j < 1000; j++) {
list.add(j);
}
System.out.println("最開始生成的集合長度:"+list.size());
//parallelStream遍歷數據的時候會產生丟失的問題
for (int i = 0; i < 10 ; i++) {
  
List<Integer> parseList = new ArrayList<>();
list.parallelStream().forEach(integer -> {
parseList.add(integer);
});
System.out.println("每次遍歷的集合長度:"+ parseList.size());
}
}

我首先創(chuàng)建了一個1000長度的集合,之后對這個集合使用多次遍歷,然而呢,會發(fā)現,最后遍歷的集合少數據,并且會在多次重復遍歷的時候數組越界..

因為這種情況,之前工作使用parallelStream出現過2次問題, 我一直以為是使用parallelStream本身不夠很安全導致的.實際上今天整理這篇博文突然才發(fā)現這個問題,就是遍歷的結果轉為的list是線程安全的么?

其實當正常進行遍歷的時候, 可以對遍歷出的結果核對,實際上每次遍歷出的結果,仍然是與原來生成的結果一致的.

所以這邊只能將鍋甩在接收這些數據的list上面了

這個時候就需要對list進行包裝

List<Integer> synchronizedList = Collections.synchronizedList(parseList);

這會在看下修改后的代碼以及結果

public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int j = 0; j < 1000; j++) {
list.add(j);
}
System.out.println("最開始生成的集合長度:"+list.size());
//parallelStream遍歷數據的時候會產生丟失的問題
for (int i = 0; i < 10 ; i++) {
  
List<Integer> parseList = new ArrayList<>();
List<Integer> synchronizedList = Collections.synchronizedList(parseList);
list.parallelStream().forEach(integer -> {
synchronizedList.add(integer);
});
System.out.println("每次遍歷的集合長度:"+ synchronizedList.size());
}
}

這樣每次遍歷的結果也都是一樣的,而且速度也會由于異步的會比之前效率提升好多

同樣的如何創(chuàng)建線程安全的set,map也就可以進行相應的包裝,這樣就避免了使用會出新一些明明感覺對,確和自己想要的結果不一致的bug

同理使用parallelStream用StringBuffer 而不適用StringBuilder,因為前者是線程安全的

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • 深入理解Java8新特性之Stream API的創(chuàng)建方式和中間操作步驟

    深入理解Java8新特性之Stream API的創(chuàng)建方式和中間操作步驟

    Stream是Java8的一大亮點,是對容器對象功能的增強,它專注于對容器對象進行各種非常便利、高效的 聚合操作(aggregate operation)或者大批量數據操作。Stream API借助于同樣新出現的Lambda表達式,極大的提高編程效率和程序可讀性,感興趣的朋友快來看看吧
    2021-11-11
  • java 中迭代器的使用方法詳解

    java 中迭代器的使用方法詳解

    這篇文章主要介紹了java 中迭代器的使用方法詳解的相關資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • 實戰(zhàn)指南:Java編寫Flink?SQL解決難題

    實戰(zhàn)指南:Java編寫Flink?SQL解決難題

    想知道如何利用Java編寫Flink?SQL解決難題嗎?本指南將為您揭示最實用的技巧和策略,讓您輕松應對挑戰(zhàn),跟著我們一起探索,讓Java和Flink?SQL成為您問題解決的得力助手!
    2023-12-12
  • Mybatis-Plus或PageHelper多表分頁查詢總條數不對問題的解決方法

    Mybatis-Plus或PageHelper多表分頁查詢總條數不對問題的解決方法

    PageHelper 這個插件用了很多次了,今天使用的時候才遇到一個問題,這篇文章主要給大家介紹了關于Mybatis-Plus或PageHelper多表分頁查詢總條數不對問題的解決方法,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • Java超詳細講解排序二叉樹

    Java超詳細講解排序二叉樹

    排序二叉樹的特點是一個父節(jié)點只能有左右兩個子節(jié)點、左節(jié)點的值比父節(jié)點要小、右節(jié)點的值要比父節(jié)點要大,難度并不大,但是得花時間來理解
    2022-06-06
  • Java編寫簡單計算器的完整實現過程

    Java編寫簡單計算器的完整實現過程

    這篇文章主要給大家介紹了關于Java編寫簡單計算器的完整實現過程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • 淺談Java基準性能測試之JMH

    淺談Java基準性能測試之JMH

    JMH是Java Microbenchmark Harness的簡稱,一個針對Java做基準測試的工具。想準確的對一段代碼做基準性能測試并不容易,因為JVM層面在編譯期、運行時對代碼做很多優(yōu)化,當代碼塊處于整個系統(tǒng)中運行時并不一定會生效,產生錯誤的基準測試結果,這個問題就是JMH要解決的
    2021-06-06
  • Java中枚舉的實現與應用詳解

    Java中枚舉的實現與應用詳解

    這篇文章主要介紹了Java中枚舉的實現與應用詳解,EnumTest中還有一個VALUES數組,里面存儲著所有的枚舉實例,調用values方法時返回VALUES數組的clone,需要的朋友可以參考下
    2023-12-12
  • JavaFX如何獲取ListView(列表視圖)的選項

    JavaFX如何獲取ListView(列表視圖)的選項

    這篇文章主要介紹了JavaFX如何獲取ListView(列表視圖)的選項,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • java 中冒泡、二分、快速算法詳解

    java 中冒泡、二分、快速算法詳解

    這篇文章主要介紹了java 中冒泡、二分、快速算法詳解的相關資料,需要的朋友可以參考下
    2017-06-06

最新評論