我正在尝试通过EA(ea-async)使用async / await库来模仿Java中Javascript中的单线程异步编程。这主要是因为我的程序中没有持久的CPU绑定计算,并且我想用Java编写无单线程锁定的代码。
ea-async库在很大程度上依赖于Java中的CompletableFuture,而Java下面似乎使用ForkJoinPool来运行异步回调。由于我的CPU是多核,这使我进入了多线程环境。似乎对于每个CompletableFuture任务,我都可以使用自定义线程池执行程序来提供异步。我可以为此提供Executors.newSingleThreadExecutor()
,但是我需要一种全局设置的方法,以便所有CompletableFuture在单个JVM进程中都将使用此执行程序。我该怎么做?
答案 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>