CompletableFuture项目实战

259 阅读1分钟

CompletableFuture项目实战

参考文献:

官方文档

CompletableFuture使用详解(全网看这一篇就行)

CompletableFutur多线程编程可以如此顺滑

CompletableFuture学习手册


一、for循环开启异步处理并等待执行结束

List<CompletableFuture<Void>> completableFutureList = new ArrayList<>(policyListV1DTOList.size());
CompletableFuture[] cfArray = new CompletableFuture[completableFutureList.size()];
for (PolicyListV1DTO dto : policyListV1DTOList) {
    if(ShuidiAssembler.isShuidiOrder(dto.getTradeOrderId())){
        continue;
    }
    // 是否具备续期条件
    if(!isInTheRenewal(dto.getPolicyStatus(), dto.getPremiumPaymentMethod(), dto.getSerialNo())){
        continue;
    }

    CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {

        // 处理续期数据
        ProcessRenewalDataDTO processRenewalDataDTO = processRenewalData(dto.getSerialNo(),dto.getProductCode());
        dto.setIsInThePayDay(processRenewalDataDTO.getIsInThePayDay());
        dto.setNextScheduleTime(processRenewalDataDTO.getNextScheduleTime());
        dto.setIsBeforePayDate(processRenewalDataDTO.getIsBeforePayDate());
        dto.setEndScheduleTime(processRenewalDataDTO.getEndScheduleTime());

    },insurePolicyThreadPoolTaskExecutor).handle( (result,ex) -> {
        if(Objects.nonNull(ex)){
            log.error("处理续期数据method#processRenewalData异常,serialNo =>{},exceptionMessage=>",dto.getSerialNo(),ex.getCause());
        }
        return null;
    });
    if(Objects.nonNull(voidCompletableFuture)){
        completableFutureList.add(voidCompletableFuture);
    }
}
CompletableFuture.allOf(completableFutureList.toArray(cfArray)).join();

二、多个任务分拆执行(业务逻辑不互通)

// 任务一
CompletableFuture<Void> runAsync1 = CompletableFuture.runAsync(() -> {
            long currentTimeMillis = System.currentTimeMillis();
            InsuredContentV3DTO insuredContentV3DTO = analysisInsuredContentDTOFromPolicyDetailEntity(policyDetailEntity);
          
            handlePolicyProtectionContentV3(v3DTO, insuredContentV3DTO);     
            handlePolicyProductClauseDTOV3(v3DTO, insuredContentV3DTO);
            handleCriticalDiseasePolicyV3(v3DTO, event.getMemberNo());
            log.info("runAsync1 =》{}",System.currentTimeMillis() - currentTimeMillis);
}, insurePolicyThreadPoolTaskExecutor);

// 任务二
PolicyInfoEntity finalPolicyInfoEntity = policyInfoEntity;
CompletableFuture<Void> runAsync2 = CompletableFuture.runAsync(() -> {
            long currentTimeMillis = System.currentTimeMillis();
            
            handlePolicyFromProductDetailRespDtoV3(v3DTO);

            
            handlePolicyFromPolicyDetailEntityV3(v3DTO, policyDetailEntity, finalPolicyInfoEntity);

            log.info("runAsync2 =》{}",System.currentTimeMillis() - currentTimeMillis);
}, insurePolicyThreadPoolTaskExecutor);

        
// 等待任务1、2线程执行完后继续往下执行
CompletableFuture.allOf(runAsync1, runAsync2).join();

X、拓展

一、自定义线程池

@Slf4j
@EnableAsync
@Configuration
public class InsuranceThreadPoolConfig {
    
    @Value("${insurance.vivocare.thread.pool.size:30}")
    private int executorVivoCareThreadPoolSize;
    @Value("${insurance.vivocare.thread.max.pool.size:50}")
    private int executorVivoCareThreadMaxPoolSize;
    @Value("${insurance.policy.thread.pool.size:30}")
    private int executorPolicyThreadPoolSize;
    @Value("${insurance.policy.thread.max.pool.size:50}")
    private int executorPolicyThreadMaxPoolSize;
    
    @Bean(name = "insureVivoCareThreadPoolTaskExecutor")
    public ThreadPoolTaskExecutor insureVivoCareThreadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new InsuranceThreadPoolTaskExecutor();
        executor.setCorePoolSize(executorVivoCareThreadPoolSize);
        executor.setMaxPoolSize(executorVivoCareThreadMaxPoolSize);
        executor.setQueueCapacity(executorThreadPoolQueueCapacity);
        executor.setKeepAliveSeconds(keepAliveSeconds);
        executor.setThreadNamePrefix("InsureVivoCareExecutor-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        // 等待所有任务结束后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.initialize();
        return executor;
    }
}

二、线程池注入

// 这里的name等于线程池中配置的Bean-name
@Resource(name = "insurePolicyThreadPoolTaskExecutor")
private ThreadPoolTaskExecutor insurePolicyThreadPoolTaskExecutor;