将 ForkJoinPool 与 AsyncHttpClient 一起使用 - 它有意义吗?

Using ForkJoinPool together with AsyncHttpClient - does it make sense?

我的问题与 this question about ForkJoinPool and IO-oriented operations, but it is slightly more general (and the question I linked to didn't receive a definite answer). In short - if I want to send many HTTP requests in parallel, and am already using an asynchronous HTTP client (such as AsyncHttpClient) 有点相关,是否也可以使用 ForkJoinPool 并行提交请求?

最初,我认为这样做违背了使用已经能够并行发送请求的异步 HTTP 客户端的目的。然而,阅读 ,其中提到 ForkJoinPool 甚至可以提高性能 "when all tasks are async and submitted to the pool rather than forked",让我怀疑我对异步操作在 Java 中的工作方式以及它们应该如何执行的理解。在我的情况下使用 ForkJoinPool 是否仍然有优势,如果有,为什么会这样?

我还阅读了 this question 关于如何在 Java 中并行发送 HTTP 请求的内容,所有答案都提到使用 ExecutorService 或 AsyncHttpClient,但没有答案同时提到两者。

它们是正交的概念,因此您没有在相同的答案中看到它们。

AsyncHttpClient 的目的是(除其他事项外)使用 单线程 进行所有网络通信(由 Netty 通过 Java 在内部执行) s NIO 以一种非阻塞的异步方式),而不是传统的每个请求一个线程的模型。在网络层的单线程之上,该库有工作线程执行 应用程序级别 异步处理 AsyncHttpClient 的用户可见,这意味着它已经有一个(小)内部线程池。

ForkJoinPool 通过 多个线程 努力最大化 CPU 使用率(公共池默认有 CPU cores - 1,您创建的可以more/less) 并通过工作窃取使线程不空闲,这对于小型递归任务最有效。

link 讨论工作窃取对于非递归任务 有效。 "async" 这个词让你大吃一惊,但它只是指你提交给池的常规任务,它是异步完成的。

所以你可以或者使用线程池执行每个请求线程(即基本I/O,或"old I/O"),你可以使用没有线程池的单线程非阻塞NIO(即新的I/O)。

将它们结合起来没有意义。您将从每个请求线程模型迁移到非阻塞模型以提高性能。