首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Java编码指南:慎用CompletableFuture中不带线程池参数的那些方法

Java编码指南:慎用CompletableFuture中不带线程池参数的那些方法

作者头像
崔认知
发布2023-06-19 16:50:15
发布2023-06-19 16:50:15
7040
举报
文章被收录于专栏:nobodynobody

CompletableFuture提供异步执行的方法总是成对的


例如:

代码语言:javascript
复制
java.util.concurrent.CompletableFuture#supplyAsync
代码语言:javascript
复制
    /**
     * Returns a new CompletableFuture that is asynchronously completed
     * by a task running in the {@link ForkJoinPool#commonPool()} with
     * the value obtained by calling the given Supplier.
     *
     * @param supplier a function returning the value to be used
     * to complete the returned CompletableFuture
     * @param <U> the function's return type
     * @return the new CompletableFuture
     */
    public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
        return asyncSupplyStage(ASYNC_POOL, supplier);
    }

    /**
     * Returns a new CompletableFuture that is asynchronously completed
     * by a task running in the given executor with the value obtained
     * by calling the given Supplier.
     *
     * @param supplier a function returning the value to be used
     * to complete the returned CompletableFuture
     * @param executor the executor to use for asynchronous execution
     * @param <U> the function's return type
     * @return the new CompletableFuture
     */
    public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
                                                       Executor executor) {
        return asyncSupplyStage(screenExecutor(executor), supplier);
    }

两个方法的重要区别是:异步运行的线程池是显示提供的,还是使用默认的

ASYNC_POOL:

代码语言:javascript
复制
/**
     * Default executor -- ForkJoinPool.commonPool() unless it cannot
     * support parallelism.
     */
    private static final Executor ASYNC_POOL = USE_COMMON_POOL ?
        ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();

CompletableFuture提供异步执行的方法,强制使用显示提供线程池


why?

1、默认提供的线程池,会使得相关的异步执行都共用一个线程池,不合理;而且不能相互隔离业务的执行;线程池的参数也不能改变

2、默认提供的线程池,在微服务spring cloud环境中,会丢失链路信息,导致链路traceId丢失;对于排查问题增加困难;

We provide LazyTraceExecutor, TraceableExecutorService, and TraceableScheduledExecutorService. Those implementations create spans each time a new task is submitted, invoked, or scheduled.‍ https://docs.spring.io/spring-cloud-sleuth/docs/current/reference/html/integrations.html#sleuth-async-executor-service-integration

3、压测链路信息丢失,因为压测链路信息存放在链路信息上下文中;

https://docs.spring.io/spring-cloud-sleuth/docs/current/reference/html/project-features.html#features-baggage https://docs.spring.io/spring-cloud-sleuth/docs/current/reference/html/project-features.html#features-baggage

4、如果默认线程池为ForkJoinPool,使得线程上下文类加载器ContextClassLoader固定为SystemClassLoader,容易导致类加载失败

小结


CompletableFuture提供异步执行的方法,强制使用显示提供线程池,能避免上述提到的一些问题。


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 认知科技技术团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档