[英]Using CompletableFuture and thread pool for a large number of tasks
[英]How to globally set thread pool for all CompletableFuture
我试图通过EA( ea-async )使用async / await库来模仿Java中Javascript中的单线程异步编程。 这主要是因为我的程序中没有持久的CPU绑定计算,并且我想用Java编写无单线程锁定的代码。
ea-async库在很大程度上依赖于Java中的CompletableFuture,而Java下面似乎使用ForkJoinPool来运行异步回调。 由于我的CPU是多核,这使我进入了多线程环境。 似乎对于每个CompletableFuture任务,我都可以使用自定义线程池执行程序来提供异步。 我可以为此提供Executors.newSingleThreadExecutor()
,但我需要一种全局设置此方法的方法,以便所有CompletableFuture在单个JVM进程中都将使用此执行器。 我该怎么做呢?
ea-async库在很大程度上依赖于Java中的CompletableFuture,而Java下面似乎使用
ForkJoinPool
来运行异步回调。
那是CompleteableFuture
的默认行为:
所有没有显式
Executor
参数的异步方法都是使用ForkJoinPool.commonPool()
执行的(除非它不支持并行度至少为2,在这种情况下,将创建一个新的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响应合并为一个队列的工作,作为单个线程将在其上工作的任务。
再说一次,我不认为您想要随之而来的一切,如果实际上您想要,那么我不明白为什么同步而不是异步工作会更好,更容易。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.