Java Completable future中的supplyAsync线程在不同的环境下使用不同的线程

问题描述 投票:0回答:1

在我的 Web 应用程序中,supplyAsync 方法在云 Linux 环境中使用 forkjoin 池,但在本地 Linux 计算机中,相同的代码使用诸如 thread-1 thread-2 之类的线程和类 Web 应用程序类加载器。是否有任何配置可以更改默认线程池以实现可完成的未来。我想获取云中的本地行为。使用 Web 应用程序类加载器进行线程化。

Java版本java 11,tomcat版本8.5.24。

CompletableFuture<Void> asyncFuture = future.thenAcceptAsync(t -> {
        if (!complete.getAndSet(true)) {
            try {
                completeAction.accept(t);
            } finally {
                synchronized (executor) {
                    K.shutdown();
                }
            }
        }
    });
    synchronized (executor) {
        if (!executor.isShutdown()) {
            executor.schedule(() -> {
                if (!complete.getAndSet(true)) {
                    try {
                        asyncFuture.cancel(false);
                        timeoutAction.run();
                    } finally {
                        executor.shutdown();
                    }
                }
            }, 200, 50);
        }
    }

java tomcat classloader completable-future
1个回答
2
投票

CompletableFuture
是否为每个任务使用新线程或
ForkJoinPool
取决于系统的并行级别:

所有没有显式 Executor 参数的异步方法都使用 ForkJoinPool.commonPool() 执行(除非它不支持至少两个并行级别,在这种情况下,将创建一个新线程来运行每个任务)。

(参见 Javadoc)。

默认并行级别比处理器数量少 1,但您可以通过设置系统属性将其更改为任何值

java.util.concurrent.ForkJoinPool.common.parallelism
(参见
ForkJoinPool
)。

但是我宁愿使用自定义的

Executor
,如对此的评论和您的上一个问题。新创建的线程继承当前线程上下文类加载器,而公共池则不然,这一事实应该更多地被视为实现细节。您的代码在这两种情况下都应该正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.