提问者:小点点

在java中使用ExecutorService完成未来


我正在尝试在java中使用ExecutorService和CompletableFuture实现一个线程池。在这里,我已经将固定大小的池传递给可完成的未来任务。如果我在可完成的未来任务中不传递这里的执行器服务,它将在我阅读时在内部使用Fork/Join公共池。现在我的问题是我应该在外部传递这里的执行器服务还是不传递,让它在内部使用Fork/Join公共池?在这种情况下哪个更好?

    ExecutorService es = Executors.newFixedThreadPool(4);
    List<CompletableFuture<?>> futures = new ArrayList<>();
    for(item i: item[]){
       CompletableFuture<Void> future = CompletableFuture.runAsync(() -> MyClass.service(i), es);
       futures.add(future);
    }
    CompletableFuture.allOf(futures.toArray(new CompletableFuture[]{})).join();

共1个答案

匿名用户

在不了解细节的情况下,不可能对您的问题给出完全准确的答案。您打算使用CompletableFuture运行哪些类型的任务?您的机器有多少CPU?

一般来说,我建议避免使用公共池,因为它可能会给您带来一些意想不到的错误,从而阻塞依赖于使用公共池的应用程序的所有部分。

更具体地说,你需要了解你将运行哪种类型的任务:阻塞还是非阻塞?阻塞任务是那些使用任何外部依赖项的任务,如数据库调用和与其他服务/应用程序的通信、同步、线程Hibernate或任何其他阻塞实用程序。

最好的方法是为阻塞任务创建一个单独的线程池,您可以完全管理它。这将允许您隔离应用程序的其他部分,并为所有非阻塞任务提供稳定和可预测的执行和性能行为。

但是,有一个有点高级的解决方法可以让您使用公共池,甚至用于阻塞任务。它是ForkJoinPool. ManagedBlocker。如果您想进行一些挖掘和实验,您可以检查官方留档。