并行流 和 串行流
送書:數據庫排名:MySQL跳出“同期跌幅榜”,拿下“漲幅榜冠軍”
0x01:并行流定義
并行流就是把一個內容分成多個數據塊,并用不同的線程分別處理每個數據塊的流。Java 8 中將并行進行了優(yōu)化,我們可以很容易的對數據進行并行操作。Stream API 可以聲明性地通過parallel() 與sequential() 在并行流與順序流之間進行切換。
流可以是順序的也可以是并行的。順序流的操作是在單線程上執(zhí)行的,而并行流的操作是在多線程上并發(fā)執(zhí)行的。
0x02:Fork/Join 框架
Fork/Join 框架:就是在必要的情況下,將一個大任務,進行拆分(fork)成若干個小任務(拆到不可再拆時),再將一個個的小任務運算的結果進行join 匯總.
:
0x03:Fork/Join 框架與傳統線程池的區(qū)別
采用“工作竊取”模式(work-stealing):當執(zhí)行新的任務時它可以將其拆分分成更小的任務執(zhí)行,并將小任務加到線程隊列中,然后再從一個隨機線程的隊列中偷一個并把它放在自己的隊列中。相對于一般的線程池實現,fork/join框架的優(yōu)勢體現在對其中包含的任務的處理方式上.在一般的線程池中,如果一個線程正在執(zhí)行的任務由于某些原因無法繼續(xù)運行,那么該線程會處于等待狀態(tài).而在fork/join框架實現中,如果某個子問題由于等待另外一個子問題的完成而無法繼續(xù)運行.那么處理該子問題的線程會主動尋找其他尚未運行的子問題來執(zhí)行.這種方式減少了線程的等待時間,提高了性能.
工作竊取模式
ForkJoin框架采用的是“工作竊取模式”,傳統線程在處理任務時,假設有一個大任務被分解成了20個小任務,并由四個線程A,B,C,D處理,理論上來講一個線程處理5個任務,每個線程的任務都放在一個隊列中,當B,C,D的任務都處理完了,而A因為某些原因阻塞在了第二個小任務上,那么B,C,D都需要等待A處理完成,此時A處理完第二個任務后還有三個任務需要處理,可想而知,這樣CPU的利用率很低。而ForkJoin采取的模式是,當B,C,D都處理完了,而A還阻塞在第二個任務時,B會從A的任務隊列的末尾偷取一個任務過來自己處理,C和D也會從A的任務隊列的末尾偷一個任務,這樣就相當于B,C,D額外幫A分擔了一些任務,提高了CPU的利用率。
實例證明是否多線程
public static void main(String[] args) {
List<Integer> data=Arrays.asList(1,2,3,4,5,6,7);
data.stream().forEach(System.out::println);
System.out.println("-----------------------------");
data.parallelStream().forEach(System.out::println);
System.out.println("*****************************");
/***
* 如果forEachOrdered()中間有其他如filter()的中介操作,會試著平行化處理,然后最終forEachOrdered()會以原數據順序處理,
* 因此,使用forEachOrdered()這類的有序處理,可能會(或完全失去)失去平行化的一些優(yōu)勢,實際上中介操作亦有可能如此,例如sorted()方法。
*/
data.parallelStream().forEachOrdered(System.out::println);
}
運行結果:
1
2
3
4
5
6
7
-----------------------------
5
4
2
7
6
3
1
*****************************
1
2
3
4
5
6
7
0x04:stream和parallelStream方法中進行選擇
是否需要并行?
你需要弄清楚你要解決的問題是什么,數據量有多大,計算的特點是什么?并不是所有的問題都適合使用并發(fā)程序來求解,比如當數據量不大時,順序執(zhí)行往往比并行執(zhí)行更快。畢竟,準備線程池和其它相關資源也是需要時間的。但是,當任務涉及到I/O操作并且任務之間不互相依賴時,那么并行化就是一個不錯的選擇。通常而言,將這類程序并行化之后,執(zhí)行速度會提升好幾個等級。
任務之間是否是獨立的?是否會引起任何競態(tài)條件?
如果任務之間是獨立的,并且代碼中不涉及到對同一個對象的某個狀態(tài)或者某個變量的更新操作,那么就表明代碼是可以被并行化的。
結果是否取決于任務的調用順序?
由于在并行環(huán)境中任務的執(zhí)行順序是不確定的,因此對于依賴于順序的任務而言,并行化也許不能給出正確的結果。
參考:
https://www.jianshu.com/p/9a11f41c2b63
https://blog.csdn.net/Keith003/article/details/80252553
https://blog.csdn.net/caishi13202/article/details/82667230
喜歡,在看
