Fork和Join是java 1.7提供的用於定型執行的框架,將大任務切分紅若干個小任務執行,小任務執行結果彙總成大任務的框架。從字面上理解就是Fork把大任務切分紅若干個小任務Join就是把小任務合併獲得大任務結果。使用工做竊取算法。java
從其餘線程裏獲取工做任務得一種算法。使用工做竊取算法能夠方便咱們將大任務切分紅多個小任務。爲了減小線程間的競爭,咱們爲每一個任務分別放入不一樣的隊列裏,線程和隊列一一對應,可是有些線程會先把任務作完,這些作完了本身任務的線程就去幫助其餘線程進行任務,這是他們會訪問同一個隊列。爲了減小竊取線程和別竊取線程之間的競爭咱們一般使用雙端隊列。被竊取線程永遠從雙端隊列的頭部獲取任務,竊取線程永遠從雙端隊列的尾部獲取內容。算法
優勢:就是充分利用線程進行並行計算,減小線程間的競爭。缺點是仍是存在競爭好比在隊列中只有一個任務時,同時也消耗了更多的系統資源建立更多的線程。框架
侷限:ide
演示代碼this
@Slf4j
public class ForkJoinTaskExample extends RecursiveTask<Integer> {
public static final int threshold = 2;
private int start;
private int end;
public ForkJoinTaskExample(int start, int end) {
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
int sum = 0;
//若是任務足夠小就計算任務
boolean canCompute = (end - start) <= threshold;
if (canCompute) {
for (int i = start; i <= end; i++) {
sum += i;
}
} else {
// 若是任務大於閾值,就分裂成兩個子任務計算
int middle = (start + end) / 2;
ForkJoinTaskExample leftTask = new ForkJoinTaskExample(start, middle);
ForkJoinTaskExample rightTask = new ForkJoinTaskExample(middle + 1, end);
// 執行子任務
leftTask.fork();
rightTask.fork();
// 等待任務執行結束合併其結果
int leftResult = leftTask.join();
int rightResult = rightTask.join();
// 合併子任務
sum = leftResult + rightResult;
}
return sum;
}
public static void main(String[] args) {
ForkJoinPool forkjoinPool = new ForkJoinPool();
//生成一個計算任務,計算1+2+3+4
ForkJoinTaskExample task = new ForkJoinTaskExample(1, 100);
//執行一個任務
Future<Integer> result = forkjoinPool.submit(task);
try {
log.info("result:{}", result.get());
} catch (Exception e) {
log.error("exception", e);
}
}
}
複製代碼