使用Fork/Join框架的目的:在多個(gè)CPU的情況下,充分利用多個(gè)CPU從而達(dá)到提高程序的運(yùn)行速度艇劫。
含義:Fork/Join框架是Java 7提供的一個(gè)用于并行執(zhí)行任務(wù)的框架橘沥,是一個(gè)把大任務(wù)分割成若干個(gè)小任務(wù)茅主,最終匯總每個(gè)小任務(wù)結(jié)果后得到大任務(wù)結(jié)果的框架嗅回。Fork/Join框架最主要的兩個(gè)關(guān)鍵詞分割和合并沐鼠,F(xiàn)ork表示分割涎显,Join表示合并坤检。
為什么需要分割和合并:
因?yàn)樵诙郈PU的情況下,可能會(huì)出現(xiàn)CPU數(shù)量>任務(wù)數(shù)量期吓,那么有的CPU就會(huì)出現(xiàn)空閑情況早歇,那么我們就將一個(gè)任務(wù)分割成幾等分,讓每個(gè)CPU都能執(zhí)行讨勤,執(zhí)行完畢之后再將任務(wù)合并成完整的任務(wù)箭跳。
以下為Fork/Join框架分析圖:
在Java的Fork/Join框架操作步驟:
1).ForkJoinTask:我們要使用Fork/Join框架,首先需要?jiǎng)?chuàng)建一個(gè)ForkJoin任務(wù)潭千。該類(lèi)提供了在任務(wù)中執(zhí)行fork和join的機(jī)制谱姓。Fork/Join框架提供了兩個(gè)子類(lèi):
????a).RecursiveAction:用于沒(méi)有返回結(jié)果的任務(wù)
????b).RecursiveTask:用于有返回結(jié)果的任務(wù)
2).ForkJoinPool:ForkJoinTask需要通過(guò)ForkJoinPool來(lái)執(zhí)行
需求:使用Fork/Join框架實(shí)現(xiàn)1-1000000總和
public class ForkJoinDemo {
public static void main(String[] args) throws Exception {
CountTask countTask = new CountTask(0,1000);
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<Long> ret = pool.submit(countTask);
System.out.println(ret.get());
}
}
class CountTask extends RecursiveTask<Long> {
private static final long threshold = 2L;// 臨界值,因?yàn)榉指钚枰R界值
private long min;
private long max;
public CountTask(long min, long max) {
this.min = min;
this.max = max;
}
@Override
protected Long compute() {
// 分割
long len = max - min;
if (len <= threshold) {// 比臨界值還小無(wú)需分割
long sum = 0;
for (long i = min; i < max; i++) {
sum += i;
}
return sum;
} else {
long mid = (max + min) / 2;//求中間值
CountTask count1 = new CountTask(min, mid);
count1.fork();
CountTask count2 = new CountTask(mid + 1, max);
count2.fork();
// 合并
return count1.join() + count2.join();
}
}
}
Fork/Join框架實(shí)現(xiàn)方式-工作竊扰偾纭:
????將任務(wù)分割出的子任務(wù)會(huì)添加到當(dāng)前工作線程所維護(hù)的雙端隊(duì)列中屉来,進(jìn)入隊(duì)列的頭部。當(dāng)一個(gè)工作線程的隊(duì)列里暫時(shí)沒(méi)有任務(wù)時(shí)狈癞,它會(huì)隨機(jī)從其他工作線程的隊(duì)列的尾部獲取一個(gè)任務(wù)(工作竊取算法)茄靠。