CompletableFuture异步编排接口优化方案

接口优化方案

(1)程序本身,减少不必要的条件判断、循环

(2)减少数据库的交互次数,以及每个sql查询的数据量(列数和行数越少越好)

(3)提高sql的性能,通过建立合适的索引

(4)使用java8的stream流提高集合的遍历操作的效率

(5)引入缓存,从redis中加载数据的效率高于mysql

(6)使用多线程异步编排,将一个大任务拆分成多个小任务并发执行,提高任务处理的效率

多线程异步编排

自定义异步编排

使用join

CompletableFuture

CompletableFuture 是 Java8 引入的一个非常强大的工具类,属于 java.util.concurrent 包,它支持异步编程和并行处理,能够更方便地处理异步计算结果。通过 CompletableFuture,你可以构建一系列异步任务,并在任务完成后执行特定的操作,或处理任务的结果。

常用方法

supplyAsync:supplyAsync是创建带有返回值的异步任务。

runAsync:runAsync是创建没有返回值的异步任务。

thenApply和thenApplyAsync:表示某个任务执行完成后执行的动作,即回调方法,会将该任务的执行结果即方法返回值作为入参传递到回调方法中,带有返回值。

thenApply和thenApplyAsync区别在于,使用thenApply方法时子任务与父任务使用的是同一个线程,而thenApplyAsync在子任务中是另起一个线程执行任务。

thenAccept和thenAcceptAsync:表示某个任务执行完成后执行的动作,即回调方法,会将该任务的执行结果即方法返回值作为入参传递到回调方法中,无返回值。

thenAccep和thenAccepAsync区别在于,使用thenAccep方法时子任务与父任务使用的是同一个线程,而thenAccepAsync在子任务中可能是另起一个线程执行任务。

thenRun和thenRunAsync:表示某个任务执行完成后执行的动作,即回调方法,无入参,无返回值。

allOf / anyOf
allOf:CompletableFuture是多个任务都执行完成后才会执行,只有有一个任务执行异常,则返回的CompletableFuture执行get方法时会抛出异常,如果都是正常执行,则get返回null。

anyOf :CompletableFuture是多个任务只要有一个任务执行完成,则返回的CompletableFuture执行get方法时会抛出异常,如果都是正常执行,则get返回执行完成任务的结果。

1、ThreadPoolConfig

全局自定义线程池配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Configuration
public class ThreadPoolConfig {

    @Bean
    public ThreadPoolExecutor threadPoolExecutor() {
        //当前系统可用的处理器数量
        int processorsCount = Runtime.getRuntime().availableProcessors();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                processorsCount * 2,
                processorsCount * 2,
                0,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(200),
                Executors.defaultThreadFactory(),
                //new ThreadPoolExecutor.CallerRunsPolicy()
                //自定义拒绝策略
                (runnable, executor) -> {
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                    }
                    //再次将拒绝任务提交给线程池执行
                    executor.submit(runnable);
                }
        );
        //线程池创建,核心线程同时创建
        //threadPoolExecutor.prestartCoreThread();
        threadPoolExecutor.prestartAllCoreThreads();
        return threadPoolExecutor;
    }
}

2、使用CompletableFuture

@Autowired
private ThreadPoolExecutor threadPoolExecutor;

public void test() {

    ItemVo itemVo = new ItemVo();
    //获取sku信息
    CompletableFuture<ProductSku> skuCompletableFuture = CompletableFuture.supplyAsync(() -> {
        //代码内容1
        return ProductSku;
    }, threadPoolExecutor);

    //获取商品信息
    CompletableFuture<Void> productComCompletableFuture = skuCompletableFuture.thenAcceptAsync(productSku ->    {  //代码内容2
    }, threadPoolExecutor);

    //获取商品最新价格
    CompletableFuture<Void> skuPriceCompletableFuture = CompletableFuture.runAsync(() -> {
        //代码内容3
    }, threadPoolExecutor);

    //获取商品详情
    CompletableFuture<Void> productDetailsComCompletableFuture = skuCompletableFuture.thenAcceptAsync(productSku -> {
       //代码内容4
    }, threadPoolExecutor);

    //获取商品规格对应商品skuId信息
    CompletableFuture<Void> skuSpecValueComCompletableFuture = skuCompletableFuture.thenAcceptAsync(productSku -> {
        //代码内容5
    }, threadPoolExecutor);

    //获取商品库存信息
    CompletableFuture<Void> skuStockVoComCompletableFuture = CompletableFuture.runAsync(() -> {
       //代码内容6
    }, threadPoolExecutor);

    //x.组合以上七个异步任务
    //多个任务都执行完成后才会执行
    CompletableFuture.allOf(
            skuCompletableFuture,
            productComCompletableFuture,
            skuPriceCompletableFuture,
            productDetailsComCompletableFuture,
            skuSpecValueComCompletableFuture,
            skuStockVoComCompletableFuture
    ).join();
    return itemVo;
}
posted @   CH_song  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示