【问题标题】:Which is better executor to pass to CompletableFuture supplyAsync Executors.newFixedThreadPool(10) or new ForkJoinPool(10)哪个更好的执行器传递给 CompletableFuture supplyAsync Executors.newFixedThreadPool(10) 或 new ForkJoinPool(10)
【发布时间】:2019-05-16 16:22:55
【问题描述】:

我正在使用 CompletableFuture.supplyAsync,我不想使用 Forkjoinpool.commonpool,我想将一个池传递给它。

目前我正在创建静态池引用并使用它,因为我不想为每个请求创建池。

我想知道以下 2 种方法中哪种方法最好。

private static ExecutorService processingPool = Executors.newFixedThreadPool(10);
CompletableFuture.supplyAsync( () -> process(),processingPool);

private static ForkJoinPool processingPool = new ForkJoinPool(10);
CompletableFuture.supplyAsync( () -> process(),processingPool);

我还读到 ForkJoinPool 在守护进程模式下创建线程。我在所有处理结束时使用“.get”阻塞调用来组合结果。所以我的问题是,如果我在上面使用 forkJoinPool,JVM 会等待完成,因为我使用了“.get”阻塞调用,还是会因为它们是守护线程而退出。

【问题讨论】:

    标签: java multithreading executorservice threadpoolexecutor forkjoinpool


    【解决方案1】:

    所以我的问题是,如果我在上面使用 forkJoinPool 当我使用“.get”阻塞调用时,JVM 会等到完成吗 还是会因为它们是守护线程而退出。

    我假设您在主线程或其他一些非守护线程中调用get()。在这种情况下,VM 不会在 get() 调用完成之前终止,因此在此之前池中的线程是守护线程还是普通线程都没有关系。

    get你的最终结果之后,你的池不再有任何任务要执行,唯一真正的问题是关于执行干净的虚拟机关闭。您应该shutdown()shutdownNow() 池,在这种情况下,您应该看到很少或没有区别。但是,如果您忽略关闭池,那么您可能会发现具有固定线程池的程序版本会缓慢终止或根本不终止。

    【讨论】:

    • 是的,我在主线程中调用 get。所以你说将 new ForkJoinPool() 传递给 supplyAsync 将使用来自新创建的池而不是来自公共池的线程。我们是否也需要为 ForkJoinPool 关闭,因为它们将是守护线程,它们一旦完成就不会被杀死。无论如何,我会做适当的关闭,但想在这里清除我的概念。当应用程序停止或服务器关闭时,我必须关闭,因为它是网络应用程序,并且我在静态上下文中创建池,因此不会为每次调用创建池。
    • @ViswaTejaKuncham,您创建的任何ExecutorService,当您不再需要它时,您应该关闭它。最迟在那时您准备终止应用程序。
    猜你喜欢
    • 2019-10-05
    • 1970-01-01
    • 2022-12-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-22
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    相关资源
    最近更新 更多