springboot项目多线程实战之异步编排任务

前提知识

创建线程的几种方式

 1.继承Thread
        Thread01 thread01 = new Thread01();
        thread01.start();//启动线程
 2.实现Runnable接口
        new Thread(new Runable01()).start();
 3.实现Callable接口+FutureTask(可以拿到返回结果,可以处理异常)
        FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
        new Thread(futureTask).start();
        //阻塞等待整个线程执行完成,获取返回结果
        Integer integer = futureTask.get();
 4.线程池
      给线程池提交任务
       ExecutorService executorService = Executors.newFixedThreadPool(10);
       executorService.execute(new Runable01());

记住!
生产实践中是使用自定义线程池! 由公司的架构师负责设计好的。

一、配置线程池

在config包下配置

@ConfigurationProperties(prefix = "mall.thread")
@Component
@Data
public class ThreadPoolConfigProperties {
    private Integer corePoolSize;
    private Integer maxSize;
    private Integer keepAliveTime;
}

可以application.yml配置线程池参数

# 线程池的配置
mall:
  thread:
    max-size: 200
    keep-alive-time: 10
    core-pool-size: 20

将线程池注入容器

@Configuration
public class MyThreadConfig {
    @Bean
    public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties pool) {
        return new ThreadPoolExecutor(pool.getCorePoolSize(),
                pool.getMaxSize(),
                pool.getKeepAliveTime(),
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(100000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardPolicy());
    }
}
实战任务
  1. sku基本信息获取 pms_sku_info
  2. sku的图片信息 pms_sku_images
  3. 获取spu的销售属性组合
  4. 获取spu的介绍 pms_spu_info_desc
  5. 获取spu的规格参数信息

1和2可以同时异步执行,3,4,5要等1的返回结果。1,2,3,4,5都完成才能返回总结果。

异步实现

CompletableFuture组合式异步编程

runAsync 和 supplyAsync方法

CompletableFuture 提供了四个静态方法来创建一个异步操作。

public static CompletableFuture<Void> runAsync(Runnable runnable)
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)

没有指定Executor的方法会使用ForkJoinPool.commonPool() 作为它的线程池执行异步代码。如果指定线程池,则使用指定的线程池运行。以下所有的方法都类同。

  • runAsync方法不支持返回值。
  • supplyAsync可以支持返回值。
实现代码
  @Override
    public SkuItemVo item(Long skuId) throws ExecutionException, InterruptedException {

        SkuItemVo skuItemVo = new SkuItemVo();

        //supplyAsync 有返回值
        CompletableFuture<SkuInfoEntity> infoFuture = CompletableFuture.supplyAsync(() -> {
            //1.sku基本信息获取 pms_sku_info
            SkuInfoEntity info = getById(skuId);
            skuItemVo.setInfo(info);
            Long spuId = info.getSpuId();
            Long catalogId = info.getCatalogId();
            return info;
        }, executor);

        //thenAcceptAsync能接受上一步结果,但是无返回值
        CompletableFuture<Void> saleAttrFuture = infoFuture.thenAcceptAsync((res) -> {
            //3.获取spu的销售属性组合
            List<SkuItemSaleAttrVo> saleAttrVos = skuSaleAttrValueService.getSaleAttrsBySpuId(res.getSpuId());
            skuItemVo.setSaleAttr(saleAttrVos);
        }, executor);

        //thenAcceptAsync能接受上一步结果,但是无返回值
        CompletableFuture<Void> descFuture = infoFuture.thenAcceptAsync((res) -> {
            //4.获取spu的介绍 pms_spu_info_desc
            SpuInfoDescEntity spuInfoDescEntity = spuInfoDescService.getById(res.getSpuId());
            skuItemVo.setDesp(spuInfoDescEntity);
        }, executor);

        //thenAcceptAsync能接受上一步结果,但是无返回值
        CompletableFuture<Void> baseAttrFuture = infoFuture.thenAcceptAsync((res) -> {
            //5.获取spu的规格参数信息
            List<SpuItemAttrGroupVo> attrGroupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId());
            skuItemVo.setGroupAttrs(attrGroupVos);
        }, executor);

        //runAsync 无返回值
        CompletableFuture<Void> imageFuture = CompletableFuture.runAsync(() -> {
            //2.sku的图片信息 pms_sku_images
            List<SkuImagesEntity> images = skuimagesService.getImagesBySkuId(skuId);
            skuItemVo.setImages(images);
        }, executor);

        //等待所有任务都完成
        CompletableFuture.allOf(saleAttrFuture, descFuture, baseAttrFuture, imageFuture).get();

        return skuItemVo;
    }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值