ForkJoinPool多任务拆分子任务

jdk1.7后提供多线程多任务拆分子任务

List datalistCar ;
 
//方式2:多任务方式
SumTask task = new SumTask(datalistCar, kafkaTemplate, 0, datalistCar.size());
//创建一个通用池,这个是jdk1.8提供的功能
ForkJoinPool pool = ForkJoinPool.commonPool();
//提交分解的SumTask 任务
Future future = pool.submit(task);
try {
    long e = System.currentTimeMillis();
    logger.warn("当前线程处理数量:" +future.get()+"原始数据量:"+ datalistCar.size() + "共耗时" + (e - s) + "毫秒");
} catch (Exception e) {
    e.printStackTrace();
} finally {
    //关闭线程池
    pool.shutdown();

}

 

/**
 * 多线程同步处理大任务拆分子任务方式
 */
public class SumTask extends RecursiveTask {
    /**
     * 每个小任务 最多只累加1000个
     */
    private static final int THRESHOLD = 1000;
    private Logger logger = LoggerFactory.getLogger(getClass());
    private KafkaTemplate kafkaTemplate;
    private List datalist;
    /**
     * 任务集合开始点
     */
    private int start;
    /**
     * 任务集合结束点
     */
    private int end;

    public SumTask(List datalist, KafkaTemplate kafkaTemplate, int start, int end) {
        this.datalist = datalist;
        this.kafkaTemplate = kafkaTemplate;
        this.start = start;
        this.end = end;
    }

    @Override
    protected Integer compute() {
        if (end-start <= THRESHOLD) {
            sendKafKa(datalist.subList(start,end));
            return end-start;
        } else {
            int middle = (start+ end)/2;
            SumTask left = new SumTask(datalist,kafkaTemplate, start, middle);
            SumTask right = new SumTask(datalist,kafkaTemplate, middle, end);
            //并行执行两个 小任务
            left.fork();
            right.fork();
            //把两个小任务累加的结果合并起来
            return left.join()+right.join();
        }
    }
private void sendKafKa(List currentList) {}

虽说了ForkJoinPool会把大任务拆分成多个子任务,但是ForkJoinPool并不会为每个子任务创建单独的线程。相反,池中每个线程都有自己的双端队列(Deque)用于存储任务。这个双端队列对于工作窃取算法至关重要。

你可能感兴趣的:(ForkJoinPool多任务拆分子任务)