多任务并发处理器-方案1(每个结果存储在自己的任务中 )

  • T 是需要用户定义自己的处理逻辑单元Task,实现 IAsynchronousRender 接口;
  • R 是Task 执行完毕后,用户希望获得的结果 Result,实现 IData 接口。
  • T 内部要把持着R的成员变量,便于后面执行完毕存储结果

先把使用方法贴上来:

  public static void main(String[] args) {
        /**
         * 任务集合
         */
        final List<IAsynchronousRender<R>> independentRenders = new ArrayList<>();

        IAsynchronousRender<R> t1 = null;
        IAsynchronousRender<R> t2 = null;
        IAsynchronousRender<R> t3 = null;

        independentRenders.add(t1);
        independentRenders.add(t2);
        independentRenders.add(t3);


        // 创建任务管理器
        FusedTaskExcutionManager<IAsynchronousRender<R>, R> excutionManager = new FusedTaskExcutionManager<>();

        //将任务集合加入任务队列
        excutionManager.addTasks(independentRenders);

        //并发渲染
        excutionManager.start();

        //获取结果
        List<R> dataList = independentRenders.stream().map(IData::getData).collect(Collectors.toList());

    }


核心类如下:

package com.example.demo.utils.poi.pool;


import com.example.demo.utils.poi.data.IAsynchronousRender;
import org.slf4j.Logger;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @param <T> 任务
 * @param <R> 结果
 * @author Rain
 * 任务执行管理器
 */
public class FusedTaskExcutionManager<T extends IAsynchronousRender<R>,R> {

    /**
     * 每个管理器,包含 指定个数的线程数
     */
    private int ThreadsOfTotal = 15;



    private final List<T> taskList = new ArrayList<>();




    /**
     * 日志
     */
    private Logger logger = null;

    public FusedTaskExcutionManager() {
     
    }

    public FusedTaskExcutionManager(int threadsOfTotal) {
        this.ThreadsOfTotal = threadsOfTotal;
    }

    public FusedTaskExcutionManager(Logger logger) {
        this.logger = logger;
    }

    /**
     * 添加任务
     *
     * @param task
     * @return
     */
    public FusedTaskExcutionManager<T, R> addTask(T task) {
        taskList.add(task);
        return this;
    }

    /**
     * 添加多个任务
     * @param tasks
     * @return
     */
    public FusedTaskExcutionManager<T, R> addTasks(Collection<T> tasks) {
        taskList.addAll(tasks);
        return this;
    }


    /**
     * @ClassName:CompletableFutureDemo
     * @Description:多线程并发任务,取结果归集
     */
    public void start() {
        //计时开始
        Long start = System.currentTimeMillis();
        //定长10线程池
        ExecutorService exs = Executors.newFixedThreadPool(ThreadsOfTotal);

        try {

            //方式:全流式处理转换成CompletableFuture[]+组装成一个无返回值CompletableFuture,join等待执行完毕。返回结果whenComplete获取
            CompletableFuture[] cfs = taskList.stream().map(object -> CompletableFuture.supplyAsync(() -> calc(object), exs).thenApply(h -> h)
                    //如需获取任务完成先后顺序,此处代码即可
                    .whenComplete((v, e) -> {
                        this.log("<----|任务" + v + "完成!result=" + v + ",异常 e=" + e + ",耗时=" + getSeconds(System.currentTimeMillis(), start));
//                        results.add(v);
                    })).toArray(CompletableFuture[]::new);
            //等待总任务完成,但是封装后无返回值,必须自己whenComplete()获取
            CompletableFuture.allOf(cfs).join();


            this.log("|<---->|任务完成先后顺序,结果集个数=" + taskList.size() + ",耗时=" + getSeconds(System.currentTimeMillis(), start));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            exs.shutdown();
        }

//        return this.results;

    }

    public static String getSeconds(long endMillis, long startMillis) {
        return (endMillis - startMillis) / 1000 + "秒";
    }


    private R calc(T t) {

        R r = null;
        try {
            //计时开始
            long start = System.currentTimeMillis();
            //渲染
            t.render();

            r = t.getData();
            //将排序号 记录到 R
//            r.setOrdexIndex(t.getOrdexIndex());
            this.log("|---->task线程:" + Thread.currentThread().getName() + "任务序号 key=" + t.getKey() + ",完成!+耗时:" + getSeconds(System.currentTimeMillis(), start));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return r;
    }


    private void log(String msg){
//        String content = msg;

//        System.out.println(msg);

        if(this.logger==null){
            System.out.println(msg);
        }else{
            this.logger.info(msg);
        }
    }

}
/**
 * 异步渲染器
 * 将 渲染后的数据 无法马上获取,需要通过单独的接口进行获取
 * @param <R>
 */
public interface IAsynchronousRender<R> extends IRender<Boolean>, IData<R> , IKeyable<String> {

}
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 具备渲染能力,渲染后的数据可以立刻返回
 * @param <O> 代表渲染结果
 */
public interface IRender<O>{


    O render();


}
/**
 * 带有数据特性,具备获取数据能力
 * @author Rain
 * @param <R> 数据
 */
public interface IData<R> {

    R getData();
}
/**
 * 逻辑唯一标识 统一接口
 * @author Rain
 * @param <T>
 */
public interface IKeyable<T> {
    T getKey();
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值