在說到並行的時候,相信很多人都會想到並發的概念。那麽並行和並發兩者壹字之差,有什麽區別呢?
並行:多個任務在同壹時間點發生,並由不同的cpu進行處理,不互相搶占資源
並行:
並發:多個任務在同壹時間點內同時發生了,但由同壹個cpu進行處理,互相搶占資源
並發:
當在大量數據處理上,數據並行化可以大量縮短任務的執行時間,將壹個數據分解成多個部分,然後並行處理,最 後將多個結果匯總,得到最終結果。
對於並行流,其在底層實現中,是沿用了Java7提供的fork/join分解合並框架進行實現。fork根據cpu核數進行數 據分塊,join對各個fork進行合並。實現過程如下所示:
對於並行流,壹定不要陷入壹個誤區:並行壹定比串行快。並行在不同的情況下它不壹定是比串行快的。影響並行 流性能主要存在5個因素:
1)數據大小:輸入數據的大小,直接影響了並行處理的性能。因為在並行內部實現中涉及到了fork/join操作,它 本身就存在性能上的開銷。因此只有當數據量很大,使用並行處理才有意義。
2)源數據結構:fork時會對源數據進行分割,數據源的特性直接影響了fork的性能。 ArrayList、數組或IntStream.range,可分解性最佳,因為他們都支持隨機讀取,因此可以被任意分割。 HashSet、TreeSet,可分解性壹般,其雖然可被分解,但因為其內部數據結構,很難被平均分解。 LinkedList、Streams.iterate、BufferedReader.lines,可分解性極差,因為他們長度未知,無法確定在哪裏進行 分割。
3)裝箱拆箱 盡量使用基本數據類型,避免裝箱拆箱。
4)CPU核數 fork的產生數量是與可用CPU核數相關,可用的核數越多,獲取的性能提升就會越大。
5)單元處理開銷 花在流中每個元素的時間越長,並行操作帶來的性能提升就會越明顯。
1)基本類型
性能消耗: Stream串行>for循環>Stream並行
2)對象
性能消耗: Stream串行>for循環>Stream並行
3)復雜對象
性能消耗: for循環>Stream串行>Stream並行
結論: 對於簡單操作,如果環境機是多核的話,建議使用Stream並行,同時在不考慮核數的情況 下,普通for循環性能要明顯高於Stream串行,相差兩倍左右。 對於復雜操作,推薦使用Stream API操作。