摘要:限制編寫并行流,存在一些與非并行流不一樣的約定。底層框架并行流在底層沿用的框架,遞歸式的分解問題,然后每段并行執(zhí)行,最終由合并結(jié)果,返回最后的值。
本書第六章的讀書筆記,也是我這個(gè)系列的最后一篇讀書筆記。后面7、8、9章分別講的“測試、調(diào)試與重構(gòu)”、“設(shè)計(jì)和架構(gòu)的原則”以及“使用Lambda表達(dá)式編寫并發(fā)程序”,因?yàn)楣P記不好整理,就不寫了,感興趣的同學(xué)自己買書來看吧。
并行化流操作關(guān)于并行與并發(fā)的區(qū)別和并行的重要性的討論這里不做筆記了,直接看Stream類庫提供了哪些關(guān)于并行的操作把。
如果已經(jīng)有了一個(gè)Stream對(duì)象,可以調(diào)用parallel方法使其擁有并行操作的能力;
如果想從一個(gè)集合類創(chuàng)建一個(gè)Stream對(duì)象,可以調(diào)用parallelStream方法獲得一個(gè)擁有并行能力的流。
BaseStream提供的sequential方法將會(huì)按順序遍歷Stream中的元素
對(duì)于同一個(gè)Stream對(duì)象,如果parallel方法和sequential方法都被調(diào)用,最后調(diào)用的那個(gè)方法將起效,不能同時(shí)處于兩種模式。
使用并行流,不需要寫代碼用于處理調(diào)度和等待線程池中的某項(xiàng)任務(wù)完成,這些工作都交由類庫完成。
限制編寫并行流,存在一些與非并行流不一樣的約定。
reduce方法的限制 初值必須為組合函數(shù)的恒等值使用恒等值與其他值做reduce運(yùn)算時(shí),其他值保持不變。比如,使用reduce進(jìn)行求和運(yùn)算時(shí),初值必須為0,而進(jìn)行求積運(yùn)算時(shí),初值必須為1
reduce操作必須符合結(jié)合律因?yàn)椴⑿杏?jì)算時(shí),元素的遍歷順序是不確定的,所以只有符合結(jié)合律才能保證結(jié)果是確定的。
避免持有鎖前面提到過,并行流的操作,是把線程的調(diào)度等工作交給了類庫解決的,所以不要做持有鎖的操作,否則是自找麻煩
性能 主要影響因素影響并行流的性能的因素主要有5個(gè):
數(shù)據(jù)大小
因?yàn)椴⑿刑幚頃?huì)帶來分解數(shù)據(jù)和合并數(shù)據(jù)的額外開銷,所以只有當(dāng)數(shù)據(jù)量足夠大時(shí)使用并行流操作才具有意義,否則就是在浪費(fèi)資源。
源數(shù)據(jù)結(jié)構(gòu)
源數(shù)據(jù)通常是集合,而因?yàn)榫唧w的類型不同,造成了分割時(shí)的開銷不同。
裝箱
基本數(shù)據(jù)類型比裝箱類型處理更快。
核的數(shù)量
擁有的核數(shù)量越多,潛在的性能提升越大。但這里的核是指運(yùn)行時(shí)進(jìn)程能夠使用的核的數(shù)量。
單元處理開銷
花在每個(gè)元素上的處理時(shí)間越長,并行帶來的性能提升越大。
底層框架并行流在底層沿用的fork/join框架,fork遞歸式的分解問題,然后每段并行執(zhí)行,最終由join合并結(jié)果,返回最后的值。
數(shù)據(jù)結(jié)構(gòu)分解的難易數(shù)據(jù)結(jié)構(gòu)對(duì)半分解的難易程度,決定了分解的效率??梢詫⒑诵念悗焯峁┑耐ㄓ脭?shù)據(jù)結(jié)構(gòu)分為三類:
性能好
ArrayList、數(shù)組或者IntStream.range這樣的支持隨機(jī)讀取的結(jié)構(gòu),能夠輕易的分解。
性能一般
HashSet、TreeSet這樣的數(shù)據(jù)結(jié)構(gòu)不易公平的分解。
性能差
有的數(shù)據(jù)結(jié)構(gòu)難于分解,有的結(jié)構(gòu)可能需要花O(N)的時(shí)間復(fù)雜度來分解。比如:LinkedList,難以對(duì)半分解;Streams.iterate和BufferedRead.lines這樣長度未知的數(shù)據(jù)結(jié)構(gòu)也難以分解。
操作的狀態(tài)流中的操作,可以分為有狀態(tài)和無狀態(tài)。無狀態(tài)的操作在整個(gè)操作中不必維護(hù)狀態(tài);有狀態(tài)的操作則有維護(hù)狀態(tài)所需的開銷和限制。
避開有狀態(tài)的操作,可以獲得更好的并行性能。無狀態(tài)的操作包括map、filter和flatMap;有狀態(tài)的操作包括sorted、distinct和limit。
并行化數(shù)組操作Java 8為數(shù)組提供了并行化操作的方法,這些方法在Arrays類中:
method | description |
---|---|
parallelPrefix | 任意給定一個(gè)函數(shù),計(jì)算數(shù)組的“和”(任意BinaryOperator) |
parallelSetAll | 使用Lambda表達(dá)式更新數(shù)組元素 |
parallelSort | 并行化對(duì)數(shù)組元素排序 |
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/66672.html
摘要:但是,最好使用差異化的類型定義,函數(shù)簽名如下其實(shí)二者說的是同一件事。后者的返回值和初始函數(shù)的返回值相同,即。破壞式更新和函數(shù)式更新的比較三的延遲計(jì)算的設(shè)計(jì)者們?cè)趯⒁霑r(shí)采取了比較特殊的方式。四匹配模式語言中暫時(shí)并未提供這一特性,略。 一、無處不在的函數(shù) 一等函數(shù):能夠像普通變量一樣使用的函數(shù)稱為一等函數(shù)(first-class function)通過::操作符,你可以創(chuàng)建一個(gè)方法引用,...
摘要:第四章引入流一什么是流流是的新成員,它允許你以聲明性方式處理數(shù)據(jù)集合通過查詢語句來表達(dá),而不是臨時(shí)編寫一個(gè)實(shí)現(xiàn)。 第四章 引入流 一、什么是流 流是Java API的新成員,它允許你以聲明性方式處理數(shù)據(jù)集合(通過查詢語句來表達(dá),而不是臨時(shí)編寫一個(gè)實(shí)現(xiàn))。就現(xiàn)在來說,你可以把它們看成遍歷數(shù)據(jù)集的高級(jí)迭代器。此外,流還可以透明地并行處理,你無需寫任何多線程代碼。 下面兩段代碼都是用來返回低...
摘要:內(nèi)部迭代與使用迭代器顯式迭代的集合不同,流的迭代操作是在背后進(jìn)行的。流只能遍歷一次請(qǐng)注意,和迭代器類似,流只能遍歷一次。 流(Stream) 流是什么 流是Java API的新成員,它允許你以聲明性方式處理數(shù)據(jù)集合(通過查詢語句來表達(dá),而不是臨時(shí)編寫一個(gè)實(shí)現(xiàn))。就現(xiàn)在來說,你可以把它們看成遍歷數(shù)據(jù)集的高級(jí)迭代器。此外,流還可以透明地并行處理,你無需寫任何多線程代碼了!我會(huì)在后面的筆記中...
摘要:新特性總覽標(biāo)簽本文主要介紹的新特性,包括表達(dá)式方法引用流默認(rèn)方法組合式異步編程新的時(shí)間,等等各個(gè)方面。還有對(duì)應(yīng)的和類型的函數(shù)連接字符串廣義的歸約匯總起始值,映射方法,二元結(jié)合二元結(jié)合。使用并行流時(shí)要注意避免共享可變狀態(tài)。 Java8新特性總覽 標(biāo)簽: java [TOC] 本文主要介紹 Java 8 的新特性,包括 Lambda 表達(dá)式、方法引用、流(Stream API)、默認(rèn)方...
摘要:本文是函數(shù)式編程第三章的讀書筆記,章名為流。正確使用表達(dá)式明確要達(dá)成什么轉(zhuǎn)化,而不是說明如何轉(zhuǎn)化沒有副作用只通過函數(shù)的返回值就能充分理解函數(shù)的全部作用函數(shù)不會(huì)修改程序或外界的狀態(tài)獲取值而不是變量避免使用數(shù)組逃過的追殺,應(yīng)該考慮優(yōu)化邏輯 本文是「Java 8 函數(shù)式編程」第三章的讀書筆記,章名為流。本章主要介紹了外部迭代與內(nèi)部迭代以及常用的高階函數(shù)。 外部迭代與內(nèi)部迭代 外部迭代 過去我...
閱讀 3114·2021-09-22 15:20
閱讀 2628·2019-08-30 15:54
閱讀 1991·2019-08-30 14:06
閱讀 3149·2019-08-30 13:05
閱讀 2490·2019-08-29 18:36
閱讀 601·2019-08-29 15:10
閱讀 549·2019-08-29 11:17
閱讀 856·2019-08-28 18:11