使用ThreadPoolExecutor的future,获取所有异步处理结果

1,262 阅读2分钟

使用场景: 在一次接口请求中,部分业务逻辑进行多线程任务处理后,获取所有异步任务的处理结果,再进行主线程的业务操作。

如下示例,只需在实际使用中稍作修改和封装,即可使用:

package com.xnyzc.lhy.mis.util.threadPoolUtil;

/**
 * @author liuju
 * @create 2020-01-07 14:08
 */

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolExecutorFutureDemo {

    private static final int CORE_POOL_SIZE = 6;
    private static final int MAX_POOL_SIZE = 10;
    private static final int QUEUE_CAPACITY = 200;
    private static final Long KEEP_ALIVE_TIME = 1L;

    public static void main(String[] args) {

        //使用阿里巴巴推荐的创建线程池的方式
        //通过ThreadPoolExecutor构造函数自定义参数创建
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                CORE_POOL_SIZE,
                MAX_POOL_SIZE,
                KEEP_ALIVE_TIME,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(QUEUE_CAPACITY),
                new ThreadPoolExecutor.CallerRunsPolicy());

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-DD HH:mm:ss SSS");
        // 线程池任务处理结果集
        List<Future<HashMap<String, String>>> futureList = new ArrayList<>();

        // 需要进行多线程处理的内容
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            list.add(i);
        }
        // 如下内容可封装成多线程处理方法
        for (int i = 0; i < list.size(); i++) {
            //提交任务到线程池
            Future<HashMap<String, String>> future = executor.submit(new Callable<HashMap<String, String>>() {
                @Override
                public HashMap<String, String> call() throws Exception {
                    System.out.println(Thread.currentThread().getName() + " 异步任务开始执行....:" + simpleDateFormat.format(new Date()));
                    // 进行业务逻辑处理
                    Thread.sleep(500);
                    System.out.println(Thread.currentThread().getName() + "异步任务执行完毕,返回执行结果!!!!" + simpleDateFormat.format(new Date()));

                    // 设置返回结果,用于计算是否所有线程已处理完
                    return new HashMap<String, String>(16) {
                        {
                            this.put("futureKey", "1");
                        }
                    };
                }
            });
            futureList.add(future);
        }
        System.out.println("====提交异步任务之后,立马返回到主线程继续往下执行" + simpleDateFormat.format(new Date()));
        try {
            Thread.sleep(1000);
        } catch (
                InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("====此时需要获取上面异步任务的执行结果" + simpleDateFormat.format(new Date()));
        boolean flag = true;
        while (flag) {
            if (!futureList.isEmpty()) {
                int count = 0;
                for (Future future : futureList) {
                    //异步任务完成并且未被取消,则获取返回的结果
                    if (future.isDone() && !future.isCancelled()) {
                        try {
                            HashMap<String, String> futureResult = (HashMap<String, String>) future.get();
                            if (!futureResult.get("futureKey").isEmpty() && futureResult.get("futureKey") != "") {
                                count = count + Integer.valueOf(futureResult.get("futureKey"));
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        } catch (ExecutionException e) {
                            e.printStackTrace();
                        }
                    }
                }
                // 判断是否所有任务已处理完成
                if (count == list.size()) {
                    System.out.println("====异步任务返回的结果成功!" + simpleDateFormat.format(new Date()));
                    flag = false;
                }
            }
        }

        System.out.println("所有任务执行完毕!!!" + simpleDateFormat.format(new Date()));
        //关闭线程池
        if (!executor.isShutdown()) {
            executor.shutdown();
        }
    }
}

运行结果: