Fork-Join框架

Fork-Join框架

Fork和Join是java 1.7提供的用於定型執行的框架,將大任務切分紅若干個小任務執行,小任務執行結果彙總成大任務的框架。從字面上理解就是Fork把大任務切分紅若干個小任務Join就是把小任務合併獲得大任務結果。使用工做竊取算法。
工做竊取算法
從其餘線程裏獲取工做任務得一種算法。使用工做竊取算法能夠方便咱們將大任務切分紅多個小任務。爲了減小線程間的競爭,咱們爲每一個任務分別放入不一樣的隊列裏,線程和隊列一一對應,可是有些線程會先把任務作完,這些作完了本身任務的線程就去幫助其餘線程進行任務,這是他們會訪問同一個隊列。爲了減小竊取線程和別竊取線程之間的競爭咱們一般使用雙端隊列。被竊取線程永遠從雙端隊列的頭部獲取任務,竊取線程永遠從雙端隊列的尾部獲取內容。

優勢:就是充分利用線程進行並行計算,減小線程間的競爭。缺點是仍是存在競爭好比在隊列中只有一個任務時,同時也消耗了更多的系統資源建立更多的線程。java

侷限:算法

  1. 在使用Fork/Join只能使用Fork和Join進行同步操做,若是在使用了其餘機制時工做線程就不能進行其餘操做了。好比在Fork/Join框架中使用了失眠,那麼在睡眠過程當中就不能執行其餘操做了。
  2. 使用Fork/Join操做的線程不能執行io操做。
  3. 不能拋出檢查異常,必須使用必要的代碼來檢查他們。

演示代碼框架

@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);
        }
    }
}
相關文章
相關標籤/搜索