如何为所有CompletableFuture全局设置线程池

时间:2019-04-29 21:45:10

标签: java

我正在尝试通过EA(ea-async)使用async / await库来模仿Java中Javascript中的单线程异步编程。这主要是因为我的程序中没有持久的CPU绑定计算,并且我想用Java编写无单线程锁定的代码。

ea-async库在很大程度上依赖于Java中的CompletableFuture,而Java下面似乎使用ForkJoinPool来运行异步回调。由于我的CPU是多核,这使我进入了多线程环境。似乎对于每个CompletableFuture任务,我都可以使用自定义线程池执行程序来提供异步。我可以为此提供Executors.newSingleThreadExecutor(),但是我需要一种全局设置的方法,以便所有CompletableFuture在单个JVM进程中都将使用此执行程序。我该怎么做?

1 个答案:

答案 0 :(得分:0)

  

ea-async库在很大程度上依赖于Java和Windows中的CompletableFuture   Java下面似乎使用ForkJoinPool运行异步回调。

这是CompleteableFuture的默认行为:

  

执行所有没有显式Executor参数的异步方法   使用ForkJoinPool.commonPool()(除非它不支持   并行度至少为两个,在这种情况下,新的Thread为   创建以运行每个任务)。对于非静态,可以重写此方法   通过定义方法defaultExecutor()来实现子类中的方法。

这是该类的已定义特征,因此,如果您使用的是类CompleteableFuture(而不是子类),并且在没有显式指定Executor的情况下生成实例,那么ForkJoinPool是什么你会得到的。

当然,如果您控制提供给ea-async的CompletableFuture,那么您可以选择提供定义defaultExecutor()的子类实例,但是您愿意。另外,您可以通过静态工厂方法创建CompleteableFuture对象,该方法允许您明确指定要使用的Executor,例如runAsync​(Runnable, Executor)

但这可能不是您真正想要的

如果您仅使用具有一个线程的执行程序,那么您的任务可以相对于提交任务的线程异步执行,是的,但是它们将相对于彼此进行序列化。您的确只有一个线程在处理它们,但是它随时会在特定的线程上工作,无论响应实际到达的顺序如何,都坚持使用该线程直到完成为止。如果这令人满意,则不清楚为什么要使用异步操作。

  

这使我进入了多线程环境,因为我的CPU是多核的。

它使您处于多个线程中,而不管您的CPU有多少个内核。这就是Executor 行为,甚至是Executors.newSingleThreadExecutor()。他们提供的就是“异步”的感觉。

如果我理解正确,那么您正在寻找使用一个线程将I / O复用到多个远程Web应用程序的方法。这就是java.nio.channels.Selector的目的,但是使用它通常需要您自己管理I / O操作或使用旨在与选择器互操作的接口。如果您被锁定在无法使用Selector的第三方接口上,那么多线程和多处理是您唯一可行的选择。

在您写的评论中:

  

我开始认为BlockingQueue可能会在   将所有API响应整合为一个队列,其中一个任务   线程将对它们起作用。

同样,我不认为您想要随之而来的一切,如果实际上您想要,那么我不明白为什么同步而不是异步工作会更好,更容易。 / p>