併發程式設計中一種經典的分而治之的思想!!
阿新 • • 發佈:2020-12-16
## 寫在前面
> 在JDK中,提供了這樣一種功能:它能夠將複雜的邏輯拆分成一個個簡單的邏輯來並行執行,待每個並行執行的邏輯執行完成後,再將各個結果進行彙總,得出最終的結果資料。有點像Hadoop中的MapReduce。
>
> ForkJoin是由JDK1.7之後提供的多執行緒併發處理框架。ForkJoin框架的基本思想是分而治之。什麼是分而治之?分而治之就是將一個複雜的計算,按照設定的閾值分解成多個計算,然後將各個計算結果進行彙總。相應的,ForkJoin將複雜的計算當做一個任務,而分解的多個計算則是當做一個個子任務來並行執行。
>
> 注:文章已同步收錄到:https://github.com/sunshinelyz/technology-binghe 和 https://gitee.com/binghe001/technology-binghe 。如果檔案對你有點幫助,別忘記給個Star哦!如果小夥伴們有任何疑問,都可以加我微信【sun_shine_lyz】進行交流哦!
## Java併發程式設計的發展
對於Java語言來說,生來就支援多執行緒併發程式設計,在併發程式設計領域也是在不斷髮展的。Java在其發展過程中對併發程式設計的支援越來越完善也正好印證了這一點。
* Java 1 支援thread,synchronized。
* Java 5 引入了 thread pools, blocking queues, concurrent collections,locks, condition queues。
* Java 7 加入了fork-join庫。
* Java 8 加入了 parallel streams。
### 併發與並行
**併發和並行在本質上還是有所區別的。**
##### 併發
併發指的是在同一時刻,只有一個執行緒能夠獲取到CPU執行任務,而多個執行緒被快速的輪換執行,這就使得在巨集觀上具有多個執行緒同時執行的效果,併發不是真正的同時執行,併發可以使用下圖表示。
![](https://img-blog.csdnimg.cn/20200411235250536.jpg)
##### 並行
並行指的是無論何時,多個執行緒都是在多個CPU核心上同時執行的,是真正的同時執行。
![](https://img-blog.csdnimg.cn/20200411235302107.jpg)
## 分治法
### 基本思想
> 把一個規模大的問題劃分為規模較小的子問題,然後分而治之,最後合併子問題的解得到原問題的解。
### 步驟
①分割原問題;
②求解子問題;
③合併子問題的解為原問題的解。
我們可以使用如下虛擬碼來表示這個步驟。
```java
if(任務很小){
直接計算得到結果
}else{
分拆成N個子任務
呼叫子任務的fork()進行計算
呼叫子任務的join()合併計算結果
}
```
在分治法中,子問題一般是相互獨立的,因此,經常通過遞迴呼叫演算法來求解子問題。
### 典型應用
* 二分搜尋
* 大整數乘法
* Strassen矩陣乘法
* 棋盤覆蓋
* 合併排序
* 快速排序
* 線性時間選擇
* 漢諾塔
## ForkJoin並行處理框架
### ForkJoin框架概述
Java 1.7 引入了一種新的併發框架—— Fork/Join Framework,主要用於實現“分而治之”的演算法,特別是分治之後遞迴呼叫的函式。
ForkJoin框架的本質是一個用於並行執行任務的框架, 能夠把一個大任務分割成若干個小任務,最終彙總每個小任務結果後得到大任務的計算結果。在Java中,ForkJoin框架與ThreadPool共存,並不是要替換ThreadPool
其實,在Java 8中引入的並行流計算,內部就是採用的ForkJoinPool來實現的。例如,下面使用並行流實現列印陣列元組的程式。
```java
public class SumArray {
public static void main(String[] args){