是否有默认的ExecutorService,或者我必须创建和维护它以获取Future对象?

9
据我所了解,获得 Future 的唯一方法是使用 ExecutorService,该服务可以通过 Executors.newFixedThreadPool(10) 来获取(顺便问一下,如何确定要使用多少个线程?有没有什么经验法则?)。
所以我不理解的是,我是否应该使用:
ExecutorService executorService = Executors.newFixedThreadPool(n);

然后将其保存(例如在某个顶级的IoC中),并在需要新的Future时调用executorService?是否有默认的Java内置ExecutorService可供使用,从而避免ExecutorService的初始化和维护的烦恼?

“default ExecutorService” 是什么意思?你想做什么? - Tunaki
2
在普通的Java中,你必须自己完成这个任务。有几个框架提供了默认值,例如 https://github.com/netty/netty/wiki/Using-as-a-generic-library#the-global-event-loop 。你需要多少线程取决于任务。CPU绑定任务大致与你拥有的CPU核心数量相同,等待IO的任务(例如等待http响应)可能需要更多。这取决于你等待的东西可以处理多少IO。FutureTask也可以为你提供没有执行器的futures(在普通的Thread中执行它们)。 - zapl
1
获取Future的唯一方法...是使用“ExecutorService”。不,您可以只实例化一个(或至少是一个具体的子类,例如“FutureTask”)。 - Andy Turner
1
Executors.newWorkStealingPool 将使用所有可用的核心。您应该为您的应用程序自己创建一个调度程序,而不是每次想要运行任务时都创建一个新的。 - Lev Kuznetsov
@zapl,谢谢,Netty项目,特别是全局事件循环看起来不错! - Tar
显示剩余4条评论
2个回答

10

默认的Java内置ExecutorService

ForkJoinPool.commonPool() - 返回公共池实例。该池是静态构建的;尝试shutdown()或shutdownNow()不会影响其运行状态。但是,该池和任何正在进行的处理都会在程序System.exit(int)时自动终止...

Future<?> future = ForkJoinPool.commonPool().submit(() -> { /* something to do */}) ;

但是有一种更现代化的方式: CompletableFuture

CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { /* something to do */});

CompletableFuture只使用这个: "所有没有显式的Executor参数的异步方法都是使用ForkJoinPool.commonPool()执行的(除非它不支持至少为2的并行级别,在这种情况下,将创建一个新线程来运行每个任务)。" https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html - James Moore
CompletableFuture并不是Executors(即commonPool)的替代品,而是提供了一个库来高效、方便地使用这些Executors。为了直接解决您的问题,您可以创建自己的Executors.new***ThreadPool(...),并使用所需的并行级别在调用CompletableFuture(.., myExecutor)时显式地使用它。 - Dmytro Sokolyuk

3

难道没有我可以使用的默认Java内置ExecutorService吗...?

在Java8中有。

阅读java.util.concurrent.CompletableFuture.supplyAsync(...)的Javadoc。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接