java fork/join框架学习,实践

1.先抄一段廖雪峰大牛对Fork/Join框架的介绍:

Java 7开始引入了一种新的Fork/Join线程池,它可以执行一种特殊的任务:把一个大任务拆成多个小任务并行执行。

我们举个例子:如果要计算一个超大数组的和,最简单的做法是用一个循环在一个线程内完成:

┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
还有一种方法,可以把数组拆成两部分,分别计算,最后加起来就是最终结果,这样可以用两个线程并行执行:

┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
如果拆成两部分还是很大,我们还可以继续拆,用4个线程并行执行:

┌─┬─┬─┬─┬─┬─┐
└─┴─┴─┴─┴─┴─┘
┌─┬─┬─┬─┬─┬─┐
└─┴─┴─┴─┴─┴─┘
┌─┬─┬─┬─┬─┬─┐
└─┴─┴─┴─┴─┴─┘
┌─┬─┬─┬─┬─┬─┐
└─┴─┴─┴─┴─┴─┘
这就是Fork/Join任务的原理:判断一个任务是否足够小,如果是,直接计算,否则,就分拆成几个小任务分别计算。这个过程可以反复“裂变”成一系列小任务。

总结步骤主要有两步:

第一、任务切分;
第二、结果合并

工作窃取(work-stealing)算法

2.使用fork/join框架编写一个求和的类

ComputerSumTask.java

package com.wying.demo.otherDemo2;

import java.util.concurrent.RecursiveTask;

/**
 * description:计算总数任务 继承 RecursiveTask类 fork/join框架的核心类
 * date: 2021/12/22
 * author: gaom
 * version: 1.0
 */
public class ComputerSumTask  extends RecursiveTask<Integer> {
    //设置任务切分的阈值
    public  static  final  int THREAD_HOLD=2;

    private  int start;
    private  int end;


    public ComputerSumTask(int start,int end){
        this.start=start;
        this.end=end;
    }

    @Override
    protected Integer compute() {
        int sum=0;
        //如果任务足够小就直接计算
        boolean b = (end - start) <= THREAD_HOLD;
        System.out.println("ThreadId:"+Thread.currentThread().getId()+" end:"+end+" start:"+start +" b:"+b);
        if(b){
            System.out.println("ThreadId:"+Thread.currentThread().getId()+" end:"+end+" start:"+start +" b:"+b+" 任务足够小直接计算 ");
            for(int i=start;i<=end;i++){
                sum+=i;
            }

        }else {

            //切分任务
            int middle = (start + end) / 2;
            ComputerSumTask computerSumTask_left = new ComputerSumTask(start, middle);
            ComputerSumTask computerSumTask_right = new ComputerSumTask(middle+1, end);
            //执行子任务
            computerSumTask_left.fork();
            computerSumTask_right.fork();
            //获取子任务结果
            int sum_left = computerSumTask_left.join();
            int sum_right = computerSumTask_right.join();
            sum = sum_left + sum_right;
            System.out.println("ThreadId:" + Thread.currentThread().getId() + " end:" + end + " start:" + start + " b:" + b + " 切分任务 sum_left:" + sum_left + " sum_right:" + sum_right + " sum:" + sum);
        }
        return sum;
    }
}

3.执行查看效果

ForkJoinMain.java

package com.wying.demo.otherDemo2;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;

/**
 * description:
 * Fork/join 框架 运行测试
 * date: 2021/12/21
 * author: gaom
 * version: 1.0
 */
public class ForkJoinMain {
    public  static  void main(String[] args) throws ExecutionException, InterruptedException {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        ComputerSumTask computerSumTask=new ComputerSumTask(1,10);
        Future<Integer> sum=forkJoinPool.submit(computerSumTask);

        System.out.print(sum.get());
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值