利用CompletableFuture实现多线程操作

一、创建线程池

@Configuration
public class ThreadPoolConfig {
    private static final Integer THREAD_CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 5;

    private static final Integer THREAD_MAX_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 20;

    private static final Integer THREAD_KEEP_ALIVE_TIME = 100;

    private static final Integer THREAD_QUEUE_CAPACITY = 100;


    /**
     * 以ArrayBlockingQueue存储线程池中元素
     * <p>
     * 该线程池已处理过MDC
     *
     * @return
     */
    @Bean("poolWithArray")
    public ThreadPoolExecutor getThreadPoolWithArray() {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                THREAD_CORE_POOL_SIZE,
                THREAD_MAX_POOL_SIZE,
                THREAD_KEEP_ALIVE_TIME,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(THREAD_QUEUE_CAPACITY),
                new MDCThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
        return executor;
    }

    /**
     * 以LinkedBlockingQueue存储线程池中元素
     * <p>
     * 该线程池已处理过MDC
     *
     * @return
     */
    @Bean("poolWithLinked")
    public ThreadPoolExecutor getThreadPoolWithLinked() {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                THREAD_CORE_POOL_SIZE,
                THREAD_MAX_POOL_SIZE,
                THREAD_KEEP_ALIVE_TIME,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(THREAD_QUEUE_CAPACITY),
                new MDCThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
        return executor;
    }

    @Bean("mdcThreadFactory")
    public ThreadFactory getThreadFactory() {
        return new MDCThreadFactory();
    }

    /**
     * 重写ThreadFactory,获取外部MDC,方便日志追踪
     */
    private class MDCThreadFactory implements ThreadFactory {
        @Override
        public Thread newThread(Runnable r) {
            MDC.put("key", "value");
            Map<String, String> copyOfContextMap = MDC.getCopyOfContextMap();
            Thread thread = new Thread() {
                @Override
                public void run() {
                    MDC.setContextMap(copyOfContextMap);
                    r.run();
                }
            };
            return thread;
        }
    }

}

二、循环获取CompletableFuture,阻塞并获取返回值

  //多线程组装计划信息返回值
        List<CompletableFuture<OperationPlanListVO>> completableFutureList = new ArrayList<>();
        for (ZhywOperationPlanEntity zhywOperationPlanEntity : zhywOperationPlanEntityList) {
            CompletableFuture<OperationPlanListVO> completableFuture = CompletableFuture.supplyAsync(() -> {
                OperationPlanListVO operationPlanListVO = OperationPlanListVO.builder()
                        .planId(zhywOperationPlanEntity.getId())
                        .planEndTime(zhywOperationPlanEntity.getPlanEndTime())
                        .planStartTime(zhywOperationPlanEntity.getPlanStartTime())
                        .endBusinessId(zhywOperationPlanEntity.getBusinessId())
                        .endBusinessName(informationComparison.get(zhywOperationPlanEntity.getBusinessId()))
                        .executeFrequencyList(StringUtils.isNotBlank(zhywOperationPlanEntity.getExecutionFrequency()) ? JSON.parseArray(zhywOperationPlanEntity.getExecutionFrequency(), String.class) : new ArrayList<>())
                        .build();
                //获取节点从属的结构名称
                String dependenceName = getDependenceName(informationComparison, zhywOperationPlanEntity.getSubordinationId());
                operationPlanListVO.setDependenceBusinessName(dependenceName);
                return operationPlanListVO;
            }, threadPoolExecutor);
            completableFutureList.add(completableFuture);
        }

        CompletableFuture<OperationPlanListVO>[] completableFutures = new CompletableFuture[completableFutureList.size()];
        completableFutureList.toArray(completableFutures);
        List<OperationPlanListVO> operationPlanListVOList = new ArrayList<>();
        try {
            CompletableFuture.allOf(completableFutures).get();
            for (CompletableFuture<OperationPlanListVO> completableFuture : completableFutureList) {
                operationPlanListVOList.add(completableFuture.get());
            }
        } catch (Exception e) {
            log.error("多线程构建计划信息列表失败,查询信息为:{},异常原因:{}", operationPlanListDTO, e);
        }

注意:这里是通过多线程,异步执行,同步阻塞后,统一获取线程得返回值。如果不需要收集返回值,则使用

CompletableFuture.runAsync()

 三、如果需要异步执行完再执行其他操作,可使用如下方式:

   CompletableFuture.runAsync(() -> {
            //重置全量业务信息对照集合
            fullIdNameMap.clear();
            Map<Long, String> allInformationComparison = getAllInformationComparison();
            if (!CollectionUtils.isEmpty(allInformationComparison)) {
                fullIdNameMap.putAll(allInformationComparison);
            }

            //重置有效的业务信息对照集合
            voidIdNameMap.clear();
            Map<Long, String> validInformationComparison = getValidInformationComparison();
            if (!CollectionUtils.isEmpty(validInformationComparison)) {
                voidIdNameMap.putAll(validInformationComparison);
            }
        }, threadPoolExecutor).thenRun(() -> {
            log.info("全量业务信息对照集合重置成功,详情:{},有效业务信息对照重置成功,详情:{}", fullIdNameMap, voidIdNameMap);
        });

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值