非同期オーケストレーション CompletableFuture の使用法

ビジネス シナリオ: 製品詳細ページでのデータ クエリ

ここに画像の説明を挿入します

ビジネス分析

製品の詳細をクエリするには多くの手順があり、一部のデータはリモートで呼び出す必要があるため、手順が多く時間がかかるこのシナリオでは、非同期メソッドを使用できます。

例:
通常の方法では、ステップごとに合計時間がクエリされます。合計所要時間 = 5 つのステップの所要時間の合計 (0.5 秒 + 0.5 秒 + 1 秒 + 1.5 秒 + 1 秒 = 合計所要時間は非同期方法では、合計消費時間 =
最大ステップ時間消費時間 (1.5 秒)

ただし、ステップ 3、4、および 5 ではステップ 1 の結果が必要ですが、ステップ 2 ではステップ 1 の結果を使用する必要がないため、ここでのビジネスを非同期方法で直接実行することはできません。非同期操作の使用について? もう 1 つの重要な点は、非同期操作の結果をどのように取得するかです。
非同期結果を取得するには、Future を使用して get()、スレッドをブロックして結果を取得する、またはポーリングして結果を取得できることがわかっています。Future は結果を取得できますが、非効率でリソースを消費します。ここでは、非同期プログラミングを実装するFutureインターフェースの実装クラス ComletableFuture ComletableFuture
の利点: (1) コールバック関数により非同期計算結果が得られる (2) 業務順序を設計できる (3) APIが豊富

1. パッケージ結果の設計

@Data
public class SkuItemVo {
    
    
    private boolean hasStock = true;
    //1.sku基本信息:title,price
    SkuInfoEntity info;
    //2.sku轮播图片
    List<SkuImagesEntity> images;
    //3.销售版本组合:颜色、版本、内存——黑色;白色;蓝色
    List<ItemSaleAttrsVo> saleAttr;
    //4.spu的商品介绍(sku共享):销售属性+展示图
    SpuInfoDescEntity desc;
    //5.规格与包装:所有属性分组下的所有属性
    List<SkuItemSaleAttrVo> groupAttrs;

    @Data
    public static class ItemSaleAttrsVo{
    
    
        private Long attrId;
        private String attrName;
        //当前属性有多少种版本:黑色,白色,蓝色
        private List<AttrValueWithSkuIdVo> attrValues;

    }

    @Data
    public static class SkuItemSaleAttrVo{
    
    
        private String groupName;
        private List<SpuBaseAttrVo> attrs;
    }

    @Data
    public static class SpuBaseAttrVo{
    
    
        private String attrName;
        private String attrValue;
    }

}

2. カスタムスレッドプール

@Configuration
public class MyThreadConfig {
    
    

    /**
     *    int corePoolSize, 核心线程数
     *    int maximumPoolSize,最新线程数
     *    long keepAliveTime, 空闲线程剩余时间
     *    TimeUnit unit,时间单位
     *    BlockingQueue<Runnable> workQueue 阻塞队列
     *    ThreadFactory threadFactory, 线程工厂
     *    RejectedExecutionHandler handler 拒绝策略
     */
    @Bean
    public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties pool){
    
    
        return new ThreadPoolExecutor(
                pool.getCoreSize(),
                pool.getMaxSize(),
                pool.getKeepAliveTime(),
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(100000),//最多存储10万异步任务
                Executors.defaultThreadFactory(),//默认工厂
                new ThreadPoolExecutor.AbortPolicy());//抛弃策略
    }
}

3. @ConfigurationProperties カスタム プロパティ。構成ファイルで使用できます。

@ConfigurationProperties(prefix = "gulimall.thread")//元数据处理器,配置问题中书写时有提示
@Component//放在容器中
@Data
public class ThreadPoolConfigProperties {
    
    
    private Integer coreSize;
    private Integer maxSize;
    private Integer KeepAliveTime;
}

アプリケーションのプロパティ

gulimall.thread.core-size=20
gulimall.thread.max-size=200
gulimall.thread.keep-alive-time=10

4. 非同期オーケストレーションの使用

	//导入线程池
	@Autowired
    ThreadPoolExecutor executor;

	//返回详情页信息
    @Override
    public SkuItemVo item(Long skuId) throws ExecutionException, InterruptedException {
    
    
        SkuItemVo skuItemVo = new SkuItemVo();

        /**
         * 1.为什么一定要使用自定义的线程池?
         * 2.执行策略:
         *  1->3,4,5
         *  2
         * 3.allof()作用
         */
        //1.sku基本信息:title,price
        CompletableFuture<SkuInfoEntity> infoFture = CompletableFuture.supplyAsync(new Supplier<SkuInfoEntity>() {
    
    
            @Override
            public SkuInfoEntity get() {
    
    
                SkuInfoEntity info = getById(skuId);
                skuItemVo.setInfo(info);
                return info;
            }
        }, executor);

        //3.销售版本组合:颜色、版本、内存
        CompletableFuture<Void> saleThread = infoFture.thenAcceptAsync(new Consumer<SkuInfoEntity>() {
    
    
            @Override
            public void accept(SkuInfoEntity skuInfoEntity) {
    
    
                List<SkuItemVo.ItemSaleAttrsVo> saleAttr = skuSaleAttrValueService.getSkuSaleAttrValue(skuInfoEntity.getSpuId());
                skuItemVo.setSaleAttr(saleAttr);
            }
        }, executor);

        //4.spu的商品介绍(sku共享):销售属性+展示图
        CompletableFuture<Void> descThread = infoFture.thenAcceptAsync(new Consumer<SkuInfoEntity>() {
    
    
            @Override
            public void accept(SkuInfoEntity skuInfoEntity) {
    
    
                SpuInfoDescEntity desc = spuInfoDescService.getById(skuInfoEntity.getSpuId());
                skuItemVo.setDesc(desc);
            }
        }, executor);

        //5.规格与包装:所有属性分组下的所有属性
        CompletableFuture<Void> attrThread = infoFture.thenAcceptAsync(new Consumer<SkuInfoEntity>() {
    
    
            @Override
            public void accept(SkuInfoEntity skuInfoEntity) {
    
    
                Long catalogId = skuInfoEntity.getCatalogId();
                List<SkuItemVo.SkuItemSaleAttrVo> groupAttrs = attrGroupService.getAttrGroupWithAttrsBySpuId(skuInfoEntity.getSpuId(), catalogId);
                skuItemVo.setGroupAttrs(groupAttrs);
            }
        }, executor);

        //2.sku轮播图片
        CompletableFuture<Void> imagesThread = CompletableFuture.runAsync(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                List<SkuImagesEntity> skuImagesEntities = skuImagesService.getImagesBySkuId(skuId);
                skuItemVo.setImages(skuImagesEntities);
            }
        }, executor);

        //等待所有任务执行结束
        CompletableFuture<Void> voidCompletableFuture = CompletableFuture.allOf(infoFture,saleThread, descThread, attrThread, imagesThread);
        voidCompletableFuture.get();

        return skuItemVo;
    }

おすすめ

転載: blog.csdn.net/weixin_44847885/article/details/131289360