java - 何时创建新的 ForkJoinPool 以及何时使用 CommonPool?

标签 java multithreading forkjoinpool

我正在阅读线程并了解了 fork/join API。

我发现您可以使用 commonPool 作为管理线程的默认池来运行线程,或者我可以将线程提交到新创建的 ForkJoinPool。

据我了解,两者的区别如下:

  • commonPool 是静态创建的主池(其中一些池方法不像它们通常对其他池所做的那样工作,例如关闭它),主要用于应用程序运行。
  • 默认/commonPool 中的并行数是核心数 - 1,其中新创建的池的默认并行数 = 核心数(或系统属性指定的数量 parallelism - 我完全忽略了合格的系统属性键名 -)。

  • 根据文档,commonPool 适用于大多数用途。

    这一切都归结为我的问题:

    我什么时候应该使用公共(public)游泳池?为什么会这样?我应该什么时候创建一个新池?为什么会这样?

    最佳答案

    短篇故事

    与软件工程中的大多数事情一样,答案是:“ 它取决于 ”。

    使用公共(public)池的优点

    如果你看this的精彩文章:

    According to Oracle’s documentation, using the predefined common pool reduces resource consumption, since this discourages the creation of a separate thread pool per task.





    Using the fork/join framework can speed up processing of large tasks, but to achieve this outcome, some guidelines should be followed:

    • Use as few thread pools as possible – in most cases, the best decision is to use one thread pool per application or system
    • Use the default common thread pool, if no specific tuning is needed
    • Use a reasonable threshold for splitting ForkJoingTask into subtasks
    • Avoid any blocking in your ForkJoingTasks


    使用专用池的优点

    但是,也有一些参数 反对 遵循这种方法:

    复杂应用程序专用池

    在复杂的应用程序中,每个逻辑工作单元都有一个专用池有时是 首选方法 。想象一个应用程序:
  • 接收大量事件并将它们分组( 可以并行完成 )
  • 然后工作人员完成工作( 也可以并行完成 )
  • 最后,一些清理工作人员进行一些清理( 也可以并行完成,)。

  • 因此,您的应用程序有 3 个逻辑工作组,每个工作组可能对并行性有自己的要求。 (请记住,此池的并行度设置为 something fairly low on most 机器)

    最好不要踩到对方的脚趾,对吧?请注意,这可以扩展到某个级别,建议为这些工作单元中的每一个提供单独的微服务,但如果由于某种原因您还没有,那么每个逻辑工作单元的专用 forkJoinPool 是 不是一个坏主意

    其他库

    如果您的应用程序代码只有一个需要并行性的地方,那么您不能保证某些开发人员不会提取一些也依赖于通用 ForkJoinPool 的 3-rd 方依赖项,并且您仍然有两个地方在这个池中需求量很大。这对于您的用例可能没问题,也可能不是,特别是如果您的默认池的并行度为 4 或更低。

    想象一下,当您的 应用程序关键代码 (例如事件处理或将数据保存到数据库)必须与一些 库竞争公共(public)池时,该库将并行 的日志导出到某个日志接收器。

    专用的 ForkJoinPool 使日志记录更整洁

    此外,常见的 forkJoinPool 具有相当非描述性的命名,因此如果您正在调试或查看日志,您可能需要筛选大量
    ForkJoinPool.commonPool-worker-xx
    在上述情况下,将其与:
    ForkJoinPool.grouping-worker-xxForkJoinPool.payload-handler-worker-xxForkJoinPool.cleanup-worker
    因此,当每个逻辑工作组使用专用的 ForkJoinPool 时,您可以看到 记录清洁度 有一些好处。

    TL;博士

    使用常见的 ForkJoinPool 具有较低的内存影响 较少的资源和线程创建以及较低的垃圾收集 需求。但是,如上所述,这种方法对于某些用例可能是不够的。

    在应用程序 中为每个逻辑工作单元使用专用的 ForkJoinPool 可提供更整洁的日志记录 ,当您的并行度级别较低 (即内核数量不多)时使用 并不是一个坏主意,并且当您想避免逻辑上的 线程争用时应用程序的不同部分 。然而, 的代价是 更高的 CPU 利用率、更高的内存开销和更多的线程创建。

    关于java - 何时创建新的 ForkJoinPool 以及何时使用 CommonPool?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57698781/

    相关文章:

    java - ForkJoinPool 调度与 ExecutorService

    java - 在用户验证中按下登录按钮后,我的代码不显示任何内容

    java - 无法建立与 Exchange Web 服务的连接 - Java API

    c++ - MFC,如何从主窗口关闭模态对话框?

    java - android 在 GridView 更新之间等待

    具有非递归任务的 Java ForkJoinPool,工作窃取是否有效?

    java - 我可以在不破坏我的自动化测试的情况下在 Hibernate 中映射一个表和同一个表的 View 吗?

    java - Fragment 启动时 OnClickListeners 不会触发

    java - 将 Java Threading Class 放到一个单独的类中

    java - 与 java8 文档中 CountedCompleter 的示例代码片段混淆