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
, andTraceableScheduledExecutorService
. 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提供异步执行的方法,强制使用显示提供线程池,能避免上述提到的一些问题。