×

《线程系列》三、ForkJoin

我的笔记 我的笔记 发表于2020-11-24 19:32:40 浏览3789 评论0

抢沙发发表评论

ForkJoin框架:

在必要情况下,将大任务拆分成一个一个小任务,然后再合并结果。

ForkJoin与线程池的区别:

窃取模式,提高性能


无标题.png


使用方法:

代码中,求0到10000000000的和,首先新建一个ForkJoinDemo(0,10000000000L)

然后进入compute方法,肯定不满足length<=BORDER

就继续拆分,有点像二分法,拆分成两个小任务,如果小任务还不满足,就再继续拆分,最后join返回

其中:BORDER是个拆分临界值,应该取平衡点

package com.fyd;

import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

public class TestForkJoin {
    public static void main(String[] args) {
        ForkJoinPool pool = new ForkJoinPool();
        ForkJoinTask forkJoinTask = new ForkJoinDemo(0, 10000000000L);
        Instant now = Instant.now();
        pool.invoke(forkJoinTask);
        Instant end = Instant.now();
        System.out.println(Duration.between(now, end));
    }
}

class ForkJoinDemo extends RecursiveTask<Long> {
    private long start;
    private long end;
    public static final long BORDER = 10000L;


    public ForkJoinDemo(long start, long end) {
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {
        long length = end - start;
        if (length <= BORDER) {
            long sum = 0;
            for (long i = 0; i < 10; i++) {
                sum += i;
            }
            return sum;
        } else {
            long mindle = (start + end) / 2;
            ForkJoinDemo left = new ForkJoinDemo(start, mindle);
            left.fork();
            ForkJoinDemo right = new ForkJoinDemo(mindle + 1, end);
            right.fork();
            return left.join() + right.join();
        }
    }
}




我的笔记博客版权我的笔记博客版权