Fork/Join并发框架,任务拆分样例和说明

                                                                 Fork/Join并发框架

这个是笔者在看书的时候随手一记;

  Fork/Join实现了ExecutorService接口的多线程处理器,可以把一个大任务划分若干的小任务

这里的运用场景是如果是大批量处理运算逻辑的数组

 这里有分俩种,一种是没有返回值的任务,一种是有返回值的任务

//没有返回值的任务样例
class RecursiveActionDemo extends RecursiveAction{

    private static final  int SPLIT_LENGTH = 2; //每次批量处理数据个数的阈值
    private List<String> tasks ; //需要处理的数据
    RecursiveActionDemo(List tasks){
        this.tasks = tasks;
    }


    @Override
    protected void compute() {
        if(tasks.size() <= SPLIT_LENGTH){
            //线程中对每一个数据都进行处理
            tasks.stream().forEach(tasks ->{
                //这里为具体的数据处理逻辑
                System.out.println(Thread.currentThread().getName()+" process task:"+tasks);
            });
        }else {
            //使用二分法将大任务分割成俩个小任务
            int middle = tasks.size() / 2 ;
            List<String> leftList = tasks.subList(0,middle);
            List<String> rightList = tasks.subList(middle,tasks.size());
            RecursiveActionDemo left =  new RecursiveActionDemo(leftList);
            RecursiveActionDemo right =  new RecursiveActionDemo(rightList);
            //并且执行俩个消任务
            left.fork();
            right.fork();

        }



    }
}



public class Test {


    public static void main(String[] args) throws InterruptedException {
        //1参加ForkJoinPool类型的线程池实例
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        //2定义好要处理的数据
        List<String> tasks = Stream.of("task1","task2","task3","task4","task5","task6","task7").collect(Collectors.toList());
        //提交可以分解的无返回值的任务
        forkJoinPool.submit(new RecursiveActionDemo(tasks));
        //4。阻塞当前线程,直到ForkjoinPool中的所有任务都执行结束
        forkJoinPool.awaitTermination(2, TimeUnit.SECONDS);
        //5关闭线程池
        forkJoinPool.shutdown();
    }
}
//RecursiveTask 为ForkJoinTask的抽象子类,该类定义了一个有返回值的任务
class RecursiveTaskDemo extends RecursiveTask<List<String>>{
    private static final  int SPLIT_LENGTH = 2; //每次批量处理数据个数的阈值
    private List<String> tasks ; //需要处理的数据
    RecursiveTaskDemo(List tasks){
        this.tasks = tasks;
    }
    @Override
    protected List<String> compute() {
        if(tasks.size() <= SPLIT_LENGTH){
            List<String> ProcessResult =  new ArrayList<>();
            //线程中对每一个数据都进行处理
            tasks.stream().forEach(tasks ->{
                //这里为具体的数据处理逻辑
                //并且将每个数据的处理结构都写入ProcessResult 集合中
                ProcessResult.add(tasks+"; processresult:finish");
            });
            return ProcessResult;
        }else {
            //使用二分法将大任务分割成俩个小任务
            int middle = tasks.size() / 2 ;
            List<String> leftList = tasks.subList(0,middle);
            List<String> rightList = tasks.subList(middle,tasks.size());
            RecursiveTaskDemo left =  new RecursiveTaskDemo(leftList);
            RecursiveTaskDemo right =  new RecursiveTaskDemo(rightList);
            //并且执行俩个消任务
            left.fork();
            right.fork();
            //将任务执行的任务结果合并后返回
            List<String> join = left.join();
            join.addAll(right.join());
            return join;

        }

    }
}






public class Test {


    public static void main(String[] args) throws InterruptedException, ExecutionException {
       //1.定义forkJoinPool
        ForkJoinPool forkJoinPool =  new ForkJoinPool(2);
       //2.定义带出来的数据
        List<String> tasks = Stream.of("task1","task2","task3","task4","task5","task6","task7").collect(Collectors.toList());
       //3.提交可分解的有返回值的RecursiveTaskDemo任务
        Future<List<String>> future = forkJoinPool.submit(new RecursiveTaskDemo(tasks));
        //4.自认为执行的结果汇总
        List<String> result =  future.get();
        System.out.println(Thread.currentThread().getName()+" process task result: "+ StringUtils.join(result,","));
        //5。关闭线程池
        forkJoinPool.shutdown();
}

俩段代码可以看的出,任务拆分利用了Fork/Join框架

ForkJoinPool:ExecutorService的实现类,负责工作的线程管理,任务队列维护即整个任务调度的流程控制,提供三种外部提交任务的方法:invoke(同步有返回值) ; execute(异步无返回值结果) ; submit(异步有返回结果,返回Future实现类,通过get获取结果);

这里提一嘴 工作线程有限处理队列中的任务(LIFO或者FIFO)顺序 这个顺序是取决于参数mode

FIFO:First Input First Output的缩写,先入先出队列,这是一种传统的按序执行方法,先进入的指令先完成并引退,跟着才执行第二条指令。

LIFO:后进先出法是指假定后入库的存货先发出,据此计算发出存货成本的方法。采用后进先出法时,每批发出存货的成本,按存货中最后入库的那批单价计算,如果发出存货的一批数量超过最后入库的那一批数量,超过部分依次按上一批入库的单价计算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值