中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

淺談JDK8并行流及串行流的區別

發布時間:2020-07-16 16:12:29 來源:億速云 閱讀:480 作者:小豬 欄目:開發技術

小編這次要給大家分享的是淺談JDK8并行流及串行流的區別,文章內容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。

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

Java 8 針對這一事實提供了新的 stream API 及簡化了創建并行集合和數組的代碼。讓我們看一下它是怎么工作的。

假設 myList 是 List<Integer> 類型的,其中包含 500,000 個Integer值。在Java 8 之前的時代中,對這些整數求和的方法是使用 for 循環完成的。

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

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

myList.stream().sum();

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

淺談JDK8并行流及串行流的區別

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

這樣就可以成功的變為并行程序,所以將一個計算擴展到線程和CPU內核上并可用很容易就可以實現。但是我們都知道,多線程和并行處理的開銷很大,所以重點是什么時候使用并行流,什么時候使用串行流才能獲得更好的性能。

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

首先,我們找到了要考慮的第一點:并非所有的stream的源會像其它的stream的源一樣可拆分。例如:ArrayList的內部實現是數組,由于可以通過計算出中間元素的索引來拆分,所以拆分這樣的源會非常容易;假如使用LinkedList,則拆分數據會復雜的多:該實現必須遍歷第一個條目中的所有元素,以便找到可以拆分的元素,所以LinkedList是并行流中性能差的例子。

淺談JDK8并行流及串行流的區別

這是我們可以保留的關于并行流性能的第一個事實:

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

拆分集合、管理 Fork/Join 任務、對象創建及 GC 也是算法上的開銷,當且僅當在CPU核心上可簡單完成或者集合足夠大時,才值得這樣做。

一個錯誤的例子:求5個整數的最大值。

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

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

舉個例子,在編寫象棋游戲的時候,對每個棋子移動的評估。每一個評估都可以并行執行,并且我們有大量可能的下一步移動。這種情形非常適合并行處理。

這是我們可以保留的關于并行流性能的第二個事實:

N * Q: 因子”元素數量” * “ 每個元素的運行成本” 應該很大

但這同樣意味著當每個元素的操作成本更高的時候,集合可以更小。或當每個元素的操作不那么占用大量CPU時,我們需要一個包含許多元素的非常大的集合,以便并行流的使用的到回報。

這直接取決于我們可以保留的第三個事實

C :CPU核心數量 - 越多越好 > 必須有1個

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

越多越好:實際上,這句話并不是在所有情況下都正確。例如:集合太小且CPU核心啟動時處于節能模式進而導致CPU無事可做。

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

要求該功能(function):

  • 獨立:每個元素的計算都不依賴或影響任何其他元素的計算
  • 無干擾:功能(function)執行的時候不會修改基礎的數據源
  • 無狀態

例:并行流中使用有狀態lamdba方法的實例,來源自 Java JDK API

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

于是,這是我們可以保留的第四個事實:

F :每個元素必須獨立

總結:

淺談JDK8并行流及串行流的區別

還有其他情況不應該并行化流嗎?有。

我們要始終考慮每一個元素的功能(function)在做什么及它是否適合運行在并行代碼中。當方法是調用一些同步方法,并行流可能會在同步方法上等待,進而導致并行流的性能并沒有想象中高。

同樣的,在調用BI/O操作時,由于數據是按照順序讀取的,以I/O源作為流,也會發生同樣的問題。

淺談JDK8并行流及串行流的區別

看完這篇關于淺談JDK8并行流及串行流的區別的文章,如果覺得文章內容寫得不錯的話,可以把它分享出去給更多人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

遂昌县| 屏东市| 香港| 平泉县| 普陀区| 共和县| 富源县| 襄汾县| 湘潭县| 邯郸市| 凭祥市| 迭部县| 乌鲁木齐县| 衡南县| 小金县| 台北县| 台南市| 高雄市| 区。| 文化| 盐山县| 西贡区| 定结县| 临洮县| 万山特区| 什邡市| 安乡县| 明光市| 杭锦后旗| 盐池县| 东山县| 固安县| 隆昌县| 黄浦区| 左贡县| 天长市| 会理县| 河津市| 大悟县| 子长县| 集安市|