CompletableFuture异步并发

之前总是写串行程序,所以19年的时候写的八字命理程序执行速度很慢,22年开始重构,应用CompletableFuture就速度飞快了。重构是一种乐趣
同时执行各自维度的分析,最后再统一汇总结果

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

  @Resource(name = "zpExecutor")
    private Executor executor;


private ZpPracticeDto getZpPracticeDto(BaZi baZi,SexEnum sex){
        CompletableFuture<List<AssertionDto>> guanluFuture = CompletableFuture.supplyAsync(()->
                guanLuService.handle(baZi, sex),executor);
        CompletableFuture<List<AssertionDto>> pengyouFuture = CompletableFuture.supplyAsync(()->
                pengyouService.handle(baZi, sex),executor);
        CompletableFuture<List<AssertionDto>> hunyinFuture = CompletableFuture.supplyAsync(()->
                hunyinService.handle(baZi, sex),executor);
        CompletableFuture<List<AssertionDto>> jieFuture = CompletableFuture.supplyAsync(()->
                jieService.handle(baZi, sex),executor);
        CompletableFuture<List<AssertionDto>> fudeFuture = CompletableFuture.supplyAsync(()->
                fudeService.handle(baZi, sex),executor);
        CompletableFuture<List<AssertionDto>> zinvFuture = CompletableFuture.supplyAsync(()->
                zinvService.handle(baZi, sex),executor);
        CompletableFuture<List<AssertionDto>> fumuFuture = CompletableFuture.supplyAsync(()->
                fumuService.handle(baZi, sex),executor);
        CompletableFuture<List<AssertionDto>> xinggeFuture = CompletableFuture.supplyAsync(()->
                xingGeService.handle(baZi, sex),executor);
        CompletableFuture<List<AssertionDto>> caiboFuture = CompletableFuture.supplyAsync(()->
                caiboService.handle(baZi, sex),executor);
        CompletableFuture<List<AssertionDto>> xiongdiFuture = CompletableFuture.supplyAsync(()->
                xiongdiService.handle(baZi, sex),executor);
        // 数据加载完成
        CompletableFuture.allOf(guanluFuture,pengyouFuture,hunyinFuture,jieFuture,fudeFuture,zinvFuture
                ,fumuFuture,xinggeFuture,caiboFuture,xiongdiFuture).join();
        //
        ZpPracticeDto zpPracticeDto = new ZpPracticeDto();
        zpPracticeDto.setBazi(baZi.toString());
        zpPracticeDto.setGuanlus(guanluFuture.join());
        zpPracticeDto.setPengyous(pengyouFuture.join());
        zpPracticeDto.setHunyins(hunyinFuture.join());
        zpPracticeDto.setJies(jieFuture.join());
        zpPracticeDto.setFudes(fudeFuture.join());
        zpPracticeDto.setZinvs(zinvFuture.join());
        zpPracticeDto.setFumus(fumuFuture.join());
        zpPracticeDto.setXingges(xinggeFuture.join());
        zpPracticeDto.setCaibos(caiboFuture.join());
        zpPracticeDto.setXiongdis(xiongdiFuture.join());
        return zpPracticeDto;
    }


import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

@EnableAsync
@Configuration
@RefreshScope
public class ThreadPoolExecutorConfig {
    @Value("${async.executor.thread.core_pool_size}")
    private int corePoolSize;
    @Value("${async.executor.thread.max_pool_size}")
    private int maxPoolSize;
    @Value("${async.executor.thread.queue_capacity}")
    private int queueCapacity;
    @Value("${async.executor.thread.name.prefix}")
    private String namePrefix;
 @Bean("zpExecutor")
    public Executor zpExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //配置核心线程数
        executor.setCorePoolSize(corePoolSize);
        //配置最大线程数
        executor.setMaxPoolSize(maxPoolSize);
        //配置队列大小
        executor.setQueueCapacity(queueCapacity);
        //配置线程池中线程的名称前缀
        executor.setThreadNamePrefix(namePrefix);
        // rejection-policy:当pool已经达到max size的时候,如何处理新任务
        // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //执行初始化
        executor.initialize();
        return executor;
    }

相关的配置如下

#配置核心线程数
async:
  executor:
    thread:
      core_pool_size: 5
      max_pool_size: 5
      queue_capacity: 10000
      name:
        prefix: qq-async-

我写的只是应用层,阿里面试:页面调10 个上游接口,如何做高并发?,理论方面可以参考这个。其实从逻辑上去分析并不难,只是很少有人具备这样的推理能力,或者即使有这种推理能力,但总结成立理论需要实践。
重构一下,分析60甲子的数据

long dd = System.currentTimeMillis();
        CompletableFuture[] futures = Arrays.stream(LiuShiJiaZiEnum.values()).map(jiazi->
            CompletableFuture.supplyAsync(()->{
                long startTime = System.currentTimeMillis();
                log.info("{}:开始执行",jiazi.display());
                BaziInfoCondDto condDto = new BaziInfoCondDto();
                condDto.setDay(jiazi.display());
                List<BaziInfo> baziInfos = baziInfoService.select(condDto);
                List<BaziInfoMogo> baziInfoMogos = new ArrayList<>();
                for (BaziInfo baziInfo: baziInfos){
                    BaziInfoMogo baziInfoMogo = baziInfoMogoService.convert(baziInfo);
                    //
                    baziInfoMogos.add(baziInfoMogo);
                }
                baziInfoMogoRepository.saveAll(baziInfoMogos);
                log.info("执行{}:{}ms" ,jiazi.display(),(System.currentTimeMillis() - startTime) );
                return String.format("任务%:执行完成",jiazi.display());
            },taskExecutor).handle((result,throwable)->{
                return result;
            }).whenComplete((r,ex)->{
                log.info("任务全都执行完成");
            })
        ).toArray(CompletableFuture[]::new);
        CompletableFuture.allOf(futures).join();
        log.info("总执行{}ms" ,(System.currentTimeMillis() - dd) );
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

warrah

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值