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

JDK8并行流及串行流區(qū)別原理詳解

 更新時(shí)間:2020年07月15日 11:31:48   作者:像風(fēng)一樣無(wú)影無(wú)起  
這篇文章主要介紹了JDK8并行流及串行流區(qū)別原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

由于處理器核心的增長(zhǎng)及較低的硬件成本允許低成本的集群系統(tǒng),致使如今并行編程無(wú)處不在,并行編程似乎是下一個(gè)大事件。

Java 8 針對(duì)這一事實(shí)提供了新的 stream API 及簡(jiǎn)化了創(chuàng)建并行集合和數(shù)組的代碼。讓我們看一下它是怎么工作的。

假設(shè) myList 是 List<Integer> 類型的,其中包含 500,000 個(gè)Integer值。在Java 8 之前的時(shí)代中,對(duì)這些整數(shù)求和的方法是使用 for 循環(huán)完成的。

for( int i : myList){
 result += i;
}

從 Java 8 開始,我們就可以使用stream完成同樣的循環(huán):

myList.stream().sum();

將此代碼改為并行處理非常簡(jiǎn)單,僅需要使用 parallelStream() 代替 stream() 或 parallel()搭配stream使用:

mylist.stream().parallelStream().sum();

這樣就可以成功的變?yōu)椴⑿谐绦?,所以將一個(gè)計(jì)算擴(kuò)展到線程和CPU內(nèi)核上并可用很容易就可以實(shí)現(xiàn)。但是我們都知道,多線程和并行處理的開銷很大,所以重點(diǎn)是什么時(shí)候使用并行流,什么時(shí)候使用串行流才能獲得更好的性能。

首先,讓我們看看在幕后發(fā)生的事情。parallel stream 使用的是 Fork/Join 框架進(jìn)行處理的,這意味著 stream 流的源會(huì)被拆分并移交給 fork/join 池中執(zhí)行。

首先,我們找到了要考慮的第一點(diǎn):并非所有的stream的源會(huì)像其它的stream的源一樣可拆分。例如:ArrayList的內(nèi)部實(shí)現(xiàn)是數(shù)組,由于可以通過(guò)計(jì)算出中間元素的索引來(lái)拆分,所以拆分這樣的源會(huì)非常容易;假如使用LinkedList,則拆分?jǐn)?shù)據(jù)會(huì)復(fù)雜的多:該實(shí)現(xiàn)必須遍歷第一個(gè)條目中的所有元素,以便找到可以拆分的元素,所以LinkedList是并行流中性能差的例子。

這是我們可以保留的關(guān)于并行流性能的第一個(gè)事實(shí):

S : 源集合必須可以有效拆分

拆分集合、管理 Fork/Join 任務(wù)、對(duì)象創(chuàng)建及 GC 也是算法上的開銷,當(dāng)且僅當(dāng)在CPU核心上可簡(jiǎn)單完成或者集合足夠大時(shí),才值得這樣做。

一個(gè)錯(cuò)誤的例子:求5個(gè)整數(shù)的最大值。

Intstream.rangeClosed(1,5).reduce(Math::max).getAsInt();

系統(tǒng)為fork/join準(zhǔn)備和處理數(shù)據(jù)的開銷非常大,以至于串行流在此場(chǎng)景中要快得多。Math.max 方法在這里的CPU開銷并不是很高,而且數(shù)據(jù)元素很少。

舉個(gè)例子,在編寫象棋游戲的時(shí)候,對(duì)每個(gè)棋子移動(dòng)的評(píng)估。每一個(gè)評(píng)估都可以并行執(zhí)行,并且我們有大量可能的下一步移動(dòng)。這種情形非常適合并行處理。

這是我們可以保留的關(guān)于并行流性能的第二個(gè)事實(shí):

N * Q: 因子”元素?cái)?shù)量” * “ 每個(gè)元素的運(yùn)行成本” 應(yīng)該很大

但這同樣意味著當(dāng)每個(gè)元素的操作成本更高的時(shí)候,集合可以更小?;虍?dāng)每個(gè)元素的操作不那么占用大量CPU時(shí),我們需要一個(gè)包含許多元素的非常大的集合,以便并行流的使用的到回報(bào)。

這直接取決于我們可以保留的第三個(gè)事實(shí)

C :CPU核心數(shù)量 - 越多越好 > 必須有1個(gè)

由于管理開銷,在單核計(jì)算機(jī)上的并行流始終比串行流的性能差。

越多越好:實(shí)際上,這句話并不是在所有情況下都正確。例如:集合太小且CPU核心啟動(dòng)時(shí)處于節(jié)能模式進(jìn)而導(dǎo)致CPU無(wú)事可做。

能否使用并行流,對(duì)每個(gè)元素的功能(function)也有要求,這涉及到并行流能否按照預(yù)期工作:

要求該功能(function):

  • 獨(dú)立:每個(gè)元素的計(jì)算都不依賴或影響任何其他元素的計(jì)算
  • 無(wú)干擾:功能(function)執(zhí)行的時(shí)候不會(huì)修改基礎(chǔ)的數(shù)據(jù)源
  • 無(wú)狀態(tài)

例:并行流中使用有狀態(tài)lamdba方法的實(shí)例,來(lái)源自 Java JDK API

Set seen = Collection.synchronizedSet(new HashSet());
stream.parallel().map( e -> {
    if(seen.add(e))
      return 0;
    else
      return e;
  })...

于是,這是我們可以保留的第四個(gè)事實(shí):

F :每個(gè)元素必須獨(dú)立

總結(jié):

還有其他情況不應(yīng)該并行化流嗎?有。

我們要始終考慮每一個(gè)元素的功能(function)在做什么及它是否適合運(yùn)行在并行代碼中。當(dāng)方法是調(diào)用一些同步方法,并行流可能會(huì)在同步方法上等待,進(jìn)而導(dǎo)致并行流的性能并沒(méi)有想象中高。

同樣的,在調(diào)用BI/O操作時(shí),由于數(shù)據(jù)是按照順序讀取的,以I/O源作為流,也會(huì)發(fā)生同樣的問(wèn)題。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • java數(shù)據(jù)庫(kù)批量插入數(shù)據(jù)的實(shí)現(xiàn)

    java數(shù)據(jù)庫(kù)批量插入數(shù)據(jù)的實(shí)現(xiàn)

    本文主要介紹了java數(shù)據(jù)庫(kù)批量插入數(shù)據(jù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • TransmittableThreadLocal線程間傳遞邏輯示例解析

    TransmittableThreadLocal線程間傳遞邏輯示例解析

    這篇文章主要介紹了TransmittableThreadLocal線程間傳遞邏輯示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • druid執(zhí)行SQL出現(xiàn)錯(cuò)誤但不影響返回結(jié)果的問(wèn)題及解決

    druid執(zhí)行SQL出現(xiàn)錯(cuò)誤但不影響返回結(jié)果的問(wèn)題及解決

    這篇文章主要介紹了druid執(zhí)行SQL出現(xiàn)錯(cuò)誤但不影響返回結(jié)果的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • springboot配置Hikari連接池方式

    springboot配置Hikari連接池方式

    本文介紹了在Springboot中配置Hikari連接池的具體參數(shù)和設(shè)置,涵蓋了autoCommit, connectionTimeout, idleTimeout, maxLifetime, minimumIdle, maximumPoolSize等關(guān)鍵配置項(xiàng),并提供了它們的默認(rèn)值、描述和條件下的重置規(guī)則
    2024-09-09
  • 詳解Java中的println輸入和toString方法的重寫問(wèn)題

    詳解Java中的println輸入和toString方法的重寫問(wèn)題

    這篇文章主要介紹了Java中的println輸入和toString方法的重寫,一個(gè)對(duì)象數(shù)組在調(diào)用Arrays.toString打印時(shí),相當(dāng)于遍歷數(shù)組,然后打印里邊每個(gè)對(duì)象,這再打印對(duì)象就調(diào)用對(duì)象自己的toString了,需要的朋友可以參考下
    2022-04-04
  • MyBatis批量插入/修改/刪除MySql數(shù)據(jù)

    MyBatis批量插入/修改/刪除MySql數(shù)據(jù)

    這篇文章主要給大家介紹了關(guān)于MyBatis批量插入/修改/刪除MySql數(shù)據(jù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • Java時(shí)間戳類Instant的使用詳解

    Java時(shí)間戳類Instant的使用詳解

    這篇文章主要為大家詳細(xì)介紹了Java中時(shí)間戳類Instant的使用方法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定幫助,需要的可以參考一下
    2022-09-09
  • Spring Boot系列教程之死信隊(duì)列詳解

    Spring Boot系列教程之死信隊(duì)列詳解

    這篇文章主要給大家介紹了關(guān)于Spring Boot系列教程之死信隊(duì)列的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • 淺談Springboot2.0防止XSS攻擊的幾種方式

    淺談Springboot2.0防止XSS攻擊的幾種方式

    本文主要介紹了Springboot2.0防止XSS攻擊的幾種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Java簡(jiǎn)單高效實(shí)現(xiàn)分頁(yè)功能

    Java簡(jiǎn)單高效實(shí)現(xiàn)分頁(yè)功能

    這篇文章主要介紹了Java簡(jiǎn)單高效實(shí)現(xiàn)分頁(yè)功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08

最新評(píng)論

永德县| 姜堰市| 万山特区| 成武县| 娄烦县| 浑源县| 上杭县| 达拉特旗| 昭通市| 镇宁| 赣榆县| 永州市| 定安县| 县级市| 阿城市| 梅河口市| 察隅县| 比如县| 德昌县| 喀喇沁旗| 巴塘县| 根河市| 水富县| 上虞市| 文成县| 纳雍县| 墨脱县| 江永县| 新津县| 三台县| 青岛市| 通州市| 樟树市| 绥阳县| 安溪县| 浏阳市| 阜城县| 海伦市| 库尔勒市| 泸州市| 西丰县|