最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

JDK8的ParallelStream遍歷無序

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

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

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

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

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

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

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

Java8 已經(jīng)很久了,現(xiàn)在都已經(jīng)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ā)現(xiàn)內(nèi)部其實使用的是下面的方法進行對集合遍歷的

內(nèi)部其實使用的還是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);
});

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

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

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

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

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遍歷數(shù)據(jù)的時候會產(chǎn)生丟失的問題
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ā)現(xiàn),最后遍歷的集合少數(shù)據(jù),并且會在多次重復(fù)遍歷的時候數(shù)組越界..

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

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

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

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

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

這會在看下修改后的代碼以及結(jié)果

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遍歷數(shù)據(jù)的時候會產(chǎn)生丟失的問題
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());
}
}

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

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

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

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

相關(guān)文章

  • 淺談SpringBoot中的@Conditional注解的使用

    淺談SpringBoot中的@Conditional注解的使用

    這篇文章主要介紹了淺談SpringBoot中的@Conditional注解的使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-04-04
  • SpringCloud-Alibaba-Sentinel服務(wù)降級,熱點限流,服務(wù)熔斷

    SpringCloud-Alibaba-Sentinel服務(wù)降級,熱點限流,服務(wù)熔斷

    這篇文章主要介紹了SpringCloud-Alibaba-Sentinel服務(wù)降級,熱點限流,服務(wù)熔斷,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • logback 實現(xiàn)給變量指定默認值

    logback 實現(xiàn)給變量指定默認值

    這篇文章主要介紹了logback 實現(xiàn)給變量指定默認值操作,具有很好的參考家價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringBoot Actuator潛在的OOM問題的解決

    SpringBoot Actuator潛在的OOM問題的解決

    本文主要介紹了SpringBoot Actuator潛在的OOM問題的解決,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • SpringBoot項目讀取外置logback配置文件的問題及解決

    SpringBoot項目讀取外置logback配置文件的問題及解決

    SpringBoot項目讀取外置logback配置文件的問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Java?for循環(huán)標簽跳轉(zhuǎn)到指定位置的示例詳解

    Java?for循環(huán)標簽跳轉(zhuǎn)到指定位置的示例詳解

    這篇文章主要介紹了Java?for循環(huán)標簽跳轉(zhuǎn)到指定位置,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • mybatis plus代碼生成器配置過程解析

    mybatis plus代碼生成器配置過程解析

    這篇文章主要介紹了mybatis plus代碼生成器配置過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • Spring boot中mongodb的使用

    Spring boot中mongodb的使用

    MongoDB是最早熱門非關(guān)系數(shù)據(jù)庫的之一,使用也比較普遍,一般會用做離線數(shù)據(jù)分析來使用,放到內(nèi)網(wǎng)的居多。這篇文章主要介紹了Spring boot中mongodb的使用,需要的朋友可以參考下
    2017-05-05
  • java實現(xiàn)文件編碼轉(zhuǎn)換的方法

    java實現(xiàn)文件編碼轉(zhuǎn)換的方法

    這篇文章主要為大家詳細介紹了java實現(xiàn)文件編碼轉(zhuǎn)換的方法,分享一個文件編碼轉(zhuǎn)換的工具類,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • Java模板動態(tài)生成word文件的方法步驟

    Java模板動態(tài)生成word文件的方法步驟

    最近項目中需要根據(jù)模板生成word文檔,模板文件也是word文檔。本文使用使用freemarker模板生成word文件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07

最新評論

洪洞县| 宝清县| 漯河市| 如东县| 康乐县| 台南市| 武川县| 乡宁县| 财经| 荔浦县| 化州市| 周口市| 鹿泉市| 青冈县| 大埔区| 南郑县| 南华县| 内江市| 盐亭县| 新兴县| 禹州市| 依安县| 边坝县| 武夷山市| 大连市| 镇雄县| 新巴尔虎左旗| 工布江达县| 龙陵县| 淮安市| 巧家县| 集贤县| 万盛区| 宽城| 昭通市| 虹口区| 县级市| 海宁市| 西昌市| 汶川县| 延安市|