亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

解決JDK8的ParallelStream遍歷無(wú)序的問(wèn)題

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

JDK8的ParallelStream遍歷無(wú)序

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

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

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

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

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

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

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

Java8 已經(jīng)很久了,現(xiàn)在都已經(jīng)Java12版本了.

我所在的上家公司,在寫(xiě)代碼時(shí)候推薦使用lambad來(lái)進(jìn)行操作遍歷集合

也就是像下面一樣

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

這種效率其實(shí)和傳統(tǒng)上的使用foreach以及for循環(huán)遍歷效果差不多,因?yàn)辄c(diǎn)開(kāi)forEach方法會(huì)發(fā)現(xiàn)內(nèi)部其實(shí)使用的是下面的方法進(jìn)行對(duì)集合遍歷的

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

因?yàn)樯厦娴谋闅v方式不會(huì)對(duì)效率有什么提升, 所以由此還有一種方式就是

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

上面的方法其實(shí)就是異步的,

這種遍歷方式因?yàn)槭钱惒奖闅v,會(huì)產(chǎn)生一種情況,就是遍歷的順序是無(wú)序的,當(dāng)然也有相應(yīng)的好處就是,遍歷速度會(huì)快,當(dāng)對(duì)生成結(jié)果不考慮排序問(wèn)題而且數(shù)據(jù)量比較大的時(shí)候可以使用.

但是,有利自然有弊,因?yàn)楫惒降乃孕枰紤]線程的問(wèn)題,就是生成的結(jié)果真的是你想要的么?

以下面的例子來(lái)運(yùn)行一段代碼:

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

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

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

其實(shí)當(dāng)正常進(jìn)行遍歷的時(shí)候, 可以對(duì)遍歷出的結(jié)果核對(duì),實(shí)際上每次遍歷出的結(jié)果,仍然是與原來(lái)生成的結(jié)果一致的.

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

這個(gè)時(shí)候就需要對(duì)list進(jìn)行包裝

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

這會(huì)在看下修改后的代碼以及結(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("最開(kāi)始生成的集合長(zhǎng)度:"+list.size());
//parallelStream遍歷數(shù)據(jù)的時(shí)候會(huì)產(chǎn)生丟失的問(wè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("每次遍歷的集合長(zhǎng)度:"+ synchronizedList.size());
}
}

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

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

同理使用parallelStream用StringBuffer 而不適用StringBuilder,因?yàn)榍罢呤蔷€程安全的

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

相關(guān)文章

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

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

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

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

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

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

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

    Mybatis-Plus或PageHelper多表分頁(yè)查詢總條數(shù)不對(duì)問(wèn)題的解決方法

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

    Java超詳細(xì)講解排序二叉樹(shù)

    排序二叉樹(shù)的特點(diǎn)是一個(gè)父節(jié)點(diǎn)只能有左右兩個(gè)子節(jié)點(diǎn)、左節(jié)點(diǎn)的值比父節(jié)點(diǎn)要小、右節(jié)點(diǎn)的值要比父節(jié)點(diǎn)要大,難度并不大,但是得花時(shí)間來(lái)理解
    2022-06-06
  • Java編寫(xiě)簡(jiǎn)單計(jì)算器的完整實(shí)現(xiàn)過(guò)程

    Java編寫(xiě)簡(jiǎn)單計(jì)算器的完整實(shí)現(xiàn)過(guò)程

    這篇文章主要給大家介紹了關(guān)于Java編寫(xiě)簡(jiǎn)單計(jì)算器的完整實(shí)現(xiàn)過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 淺談Java基準(zhǔn)性能測(cè)試之JMH

    淺談Java基準(zhǔn)性能測(cè)試之JMH

    JMH是Java Microbenchmark Harness的簡(jiǎn)稱,一個(gè)針對(duì)Java做基準(zhǔn)測(cè)試的工具。想準(zhǔn)確的對(duì)一段代碼做基準(zhǔn)性能測(cè)試并不容易,因?yàn)镴VM層面在編譯期、運(yùn)行時(shí)對(duì)代碼做很多優(yōu)化,當(dāng)代碼塊處于整個(gè)系統(tǒng)中運(yùn)行時(shí)并不一定會(huì)生效,產(chǎn)生錯(cuò)誤的基準(zhǔn)測(cè)試結(jié)果,這個(gè)問(wèn)題就是JMH要解決的
    2021-06-06
  • Java中枚舉的實(shí)現(xiàn)與應(yīng)用詳解

    Java中枚舉的實(shí)現(xiàn)與應(yīng)用詳解

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

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

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

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

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

最新評(píng)論