Java 1.7 引入了一種新的并發(fā)框架—— Fork/Join Framework
它和ExecutorService使用的場景不同,在一些場景下闷沥,F(xiàn)orkJoinPool 的性能要超過ExecutorService
ForkJoinPool 主要思想就是分而治之歹篓,在能夠用分治算法的場景下瘫证,F(xiàn)orkJoinPool 有很高的效率。
ForkJoinPool 最適合的是計算密集型的任務(wù)庄撮,如果存在 I/O背捌,線程間同步,sleep() 等會造成線程長時間阻塞的情況時洞斯,最好配合使用 ManagedBlocker毡庆。
下面用ForkJoinPool 來計算 1 累加到 99999
、烙如、么抗、
public class ForkJoinTest {
/**
* 最小處理任務(wù)單元
*/
private static final int MIN_FORK = 2;
public static void main(String[] args) throws Exception {
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTest.ForkJoinSumTask sumTask = new ForkJoinTest().new ForkJoinSumTask(1, 99999);
//提交任務(wù) 和 ExecutorService 是一樣的,只不過返回值是一個ForkJoinTask
ForkJoinTask<Integer> joinTask = pool.submit(sumTask);
System.out.println(joinTask.get());
}
/**
* 簡單的累加任務(wù)
*/
public class ForkJoinSumTask extends RecursiveTask<Integer> {
int sum;
int start;
int end;
public ForkJoinSumTask(int start, int end) {
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
//小于最小任務(wù)單元 直接處理,不需要新增任務(wù)并行處理
if (start - end < MIN_FORK) {
for (int i = start; i <= end; i++) {
sum += i;
}
return sum;
}
//取中位數(shù)
int midNum = (start + end) / 2;
ForkJoinSumTask left = new ForkJoinSumTask(start, midNum);
ForkJoinSumTask right = new ForkJoinSumTask(midNum + 1, end);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//不能這樣fork 會導(dǎo)致本線程資源浪費(fèi)
// left.fork();
// right.join();
invokeAll(left, right);
sum = left.join() + right.join();
return sum;
}
}
}
亚铁、蝇刀、、
實現(xiàn)fork/join主要是能夠使任務(wù)拆解徘溢,然后在分而治之吞琐。這里我們將1 ~ 99999 的累加進(jìn)行拆分開計算,每次都一份為二然爆,從這里看站粟,二分查詢也很適合用。這里主要注意一下我們在一份為二的時候曾雕,不要把left 與right 都fork,這會導(dǎo)致本線程沒事干奴烙,光等在這里,應(yīng)該使用只帶的invokerAll(),它在底層調(diào)用的時候默認(rèn)第一個使用了invoker,其他用了fork 保證本線程不空等剖张。