简体   繁体   English

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

[英]How to globally set thread pool for all CompletableFuture

I am trying to mimic what single threaded async programming in Javascript in Java with the use of async / await library by EA ( ea-async ). 我试图通过EA( ea-async )使用async / await库来模仿Java中Javascript中的单线程异步编程。 This is mainly because I do not have long-lasting CPU bound computations in my program and I want to code single thread lock free code in Java. 这主要是因为我的程序中没有持久的CPU绑定计算,并且我想用Java编写无单线程锁定的代码。

ea-async library heavily relies on the CompletableFuture in Java and underneath Java seems to use ForkJoinPool to run the async callbacks. ea-async库在很大程度上依赖于Java中的CompletableFuture,而Java下面似乎使用ForkJoinPool来运行异步回调。 This puts me into multi threaded environment as my CPU is multi-core. 由于我的CPU是多核,这使我进入了多线程环境。 It seems for every CompletableFuture task, I can supply async with my custom thread pool executor. 似乎对于每个CompletableFuture任务,我都可以使用自定义线程池执行程序来提供异步。 I can supply Executors.newSingleThreadExecutor() for this but I need a way to set this globally so that all CompletableFuture will be using this executor within the single JVM process. 我可以为此提供Executors.newSingleThreadExecutor() ,但我需要一种全局设置此方法的方法,以便所有CompletableFuture在单个JVM进程中都将使用此执行器。 How do I do this? 我该怎么做呢?

ea-async library heavily relies on the CompletableFuture in Java and underneath Java seems to use ForkJoinPool to run the async callbacks. ea-async库在很大程度上依赖于Java中的CompletableFuture,而Java下面似乎使用ForkJoinPool来运行异步回调。

That is the default behavior of CompleteableFuture : 那是CompleteableFuture的默认行为:

All async methods without an explicit Executor argument are performed using the ForkJoinPool.commonPool() (unless it does not support a parallelism level of at least two, in which case, a new Thread is created to run each task). 所有没有显式Executor参数的异步方法都是使用ForkJoinPool.commonPool()执行的(除非它不支持并行度至少为2,在这种情况下,将创建一个新的Thread来运行每个任务)。 This may be overridden for non-static methods in subclasses by defining method defaultExecutor() . 对于子类中的非静态方法,可以通过定义方法defaultExecutor()来重写此方法。

That's a defined characteristic of the class, so if you're using class CompleteableFuture , not a subclass, and generating instances without specifying an Executor explicitly, then a ForkJoinPool is what you're going to get. 这是该类的定义特征,因此,如果您使用的是CompleteableFuture类(而不是子类),并且在未显式指定Executor情况下生成实例,那么您将获得ForkJoinPool

Of course, if you are in control of the CompletableFuture s provided to ea-async then you have the option to provide instances of a subclass that defines defaultExecutor() however you like. 当然,如果您控制提供给ea-async的CompletableFuture ,则可以选择提供一个子类实例,该子类定义您喜欢的defaultExecutor() Alternatively, you can create your CompleteableFuture objects via the static factory methods that allow you to explicitly specify the Executor to use, such as runAsync​(Runnable, Executor) . 或者,您可以通过静态工厂方法创建CompleteableFuture对象,该方法允许您显式指定要使用的Executor ,例如runAsync​(Runnable, Executor)

But that's probably not what you really want to do . 但这可能不是您真正想做的

If you use an executor with only one thread, then your tasks can be executed asynchronously with respect to the thread that submits them, yes, but they will be serialized with respect to each other . 如果只使用一个执行程序,则可以相对于提交任务的线程异步执行任务,是的, 但是它们将相对于彼此进行序列化 You do get only one thread working on them, but it will at any time be working on a specific one, sticking with that one only until it finishes, regardless of the order in which the responses actually arrive. 您的确只有一个线程在处理它们,但是它随时会在特定的线程上工作,无论响应实际到达的顺序如何,都坚持使用该线程直到完成为止。 If that's satisfactory, then it's unclear why you want async operations at all. 如果这令人满意,则不清楚为什么要使用异步操作。

This puts me into multi threaded environment as my CPU is multi-core. 由于我的CPU是多核,这使我进入了多线程环境。

It puts you in multiple threads regardless of how many cores your CPU has. 无论您的CPU有多少个内核,它都会使您处于多个线程中。 That's what Executor s do , even Executors.newSingleThreadExecutor() . 这就是Executor 就做 ,甚至Executors.newSingleThreadExecutor() That's the sense of "asynchronous" they provide. 他们提供的就是“异步”的感觉。

If I understand correctly, you are instead looking to use one thread to multiplex I/O to multiple remote web applications. 如果我理解正确,那么您正在寻找使用一个线程将I / O复用到多个远程Web应用程序的方法。 That is what java.nio.channels.Selector is for, but using that generally requires either managing the I/O operations yourself or using interfaces designed to interoperate with selectors. 那就是java.nio.channels.Selector目的,但是使用它通常需要您自己管理I / O操作或使用旨在与选择器互操作的接口。 If you are locked in to third-party interfaces that do not afford use of a Selector , then multithreading and multiprocessing are your only viable alternatives. 如果您被锁定在不能使用Selector的第三方接口上,那么多线程和多处理是唯一可行的选择。

In comments you wrote: 在评论中,您写道:

I'm starting to think maybe BlockingQueue might do the job in consolidating all API responses into one queue as tasks where a single thread will work on them. 我开始认为,BlockingQueue可能会完成将所有API响应合并为一个队列的工作,作为单个线程将在其上工作的任务。

Again, I don't think that you want everything that comes with that, and if in fact you do, then I don't see why it wouldn't be even better and easier to work synchronously instead of asynchronously. 再说一次,我不认为您想要随之而来的一切,如果实际上您想要,那么我不明白为什么同步而不是异步工作会更好,更容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM