Java 并发编程 Fork Join 一

“分而治之”一直是一个非常有效地处理大量数据的方法。著名的MapReduce也是采取了分而治之的思想。 Fork就是分解任务,而Join 在Java线程中是等待意思 ,也就是等待计算结果。在实际应用中如果毫无顾忌地使用fork开启线程进行处理,那么很多可能会导致系统开启过多的线程而严重影响性能。所以在JDK中,给出了一个ForJoinPool线程池,对于fork方法并不急着开启线程,而是提交给ForkJoinPool线程池进行处理,以节省系统资源。

使用fork/Join 进行数据处理时的总体结构如图:

这里写图片描述

可以向ForkJoinPool线程池提交一个ForkJoinTask任务。所谓ForkJoinTask任务就是支持fork分解以及join等待的任务。ForkJoinTask有两个重要的子类 RecursiveAction和RecursiveTask。分别表示没有返回值的任务和可以携带返回值的任务。

public class CountTask extends RecursiveTask<Long> {

    private static final int threshold = 1000;

    private List<Integer> list;

    public CountTask(List<Integer> list) {

        this.list = list;

    }

    @Override
    protected Long compute() {
        long result = 0L;
        int size = list.size();
        System.out.println("size " + size);
        if (size <= threshold) {
            for (Integer i : list) {
                result += i;
            }

        } else {
            int count = size / threshold + 1;

            List<CountTask> taskList = new ArrayList<CountTask>();
            for (int i = 0; i < count; i++) {
                int toindex = 0;
                if (size < ((i + 1) * threshold)) {
                    toindex = size;
                } else {
                    toindex = (i + 1) * threshold;
                }
                int fromIndex =i * threshold;
                System.out.println("fromIndex  " + fromIndex +"<><>"+"toindex  " + toindex);
                List<Integer> subList = list.subList(fromIndex, toindex);
                CountTask c = new CountTask(subList);
                taskList.add(c);
                // c.fork();

                c.fork();

            }
            for (CountTask c : taskList) {
                result += c.join();
            }
        }

        return result;
    }

    public static void main(String args[]) {

        ForkJoinPool fp = new ForkJoinPool();
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < 903000; i++) {
            list.add(i);
        }
        CountTask task = new CountTask(list);
        ForkJoinTask<Long> re = fp.submit(task);

        try {
            long res = re.get();
            System.out.println(res);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值