【问题标题】:java fork-join executor usage for db access用于数据库访问的 java fork-join 执行器用法
【发布时间】:2015-02-26 21:54:23
【问题描述】:

ForkJoinTask 明确指出“可细分任务也不应该执行阻塞 I/O”。它的主要目标是“计算任务计算纯函数或对纯孤立对象进行操作”。我的问题是:-

  1. 为什么要设计 ForkJoinTask 来限制阻塞 IO 任务?
  2. 如果我实现阻塞 IO 任务有什么问题?
  3. 为什么 spring 和 play 框架都充满了使用 fork-join 执行器进行 DB 调用的示例?

在我的场景中,单个请求执行两种类型的工作,其中一种是加密,它将 CPU 核心推到 100% 持续 200 毫秒,其次是很少的数据库调用。任何类型的静态分区,例如用于加密的 6 个线程和用于阻塞 IO 的 2 个线程,都不会提供 CPU 的最佳使用率。因此,拥有一个 fork-join 执行器,在线程数量上超过总 CPU 计数的一定程度的过度配置,再加上工作窃取,将确保更好地使用 CPU 资源。

我对 forkjoin executor 的上述假设和理解是否正确,如果不正确,请指出差距。

【问题讨论】:

    标签: java parallel-processing executorservice fork-join forkjoinpool


    【解决方案1】:

    为什么要设计 ForkJoinTask 来限制阻塞 IO 任务?

    fork 连接池的基础是共享线程数量,如果这些线程上有一些 IO 工作阻塞,那么 CPU 密集型工作的线程就会减少。其他没有阻塞的工作会饿死。

    如果我实现阻塞 IO 任务有什么问题?

    通常,FJPool 分配的线程与处理器的数量有关。因此,如果您必须在线程上使用 IO 阻塞,请确保为其他任务分配足够的线程。

    您还可以在不与 FJ 池共享的专用线程上隔离您的 IO 工作。但是您调用blocking IO,您的线程会阻塞并被安排执行其他任务,直到解除阻塞

    为什么 spring 和 play 框架都充满了使用 fork-join 执行器进行 DB 调用的示例?

    play 也不例外。他们为 IO 任务使用专用的pools,因此其他任务不会受到影响。

    【讨论】:

      【解决方案2】:

      框架不限制任何类型的处理。不建议做阻塞之类的。我几年前写过一篇关于这个框架的评论,这里是recommendations.上的观点这是针对Java7版本的,但它仍然适用于Java8。

      阻塞不是致命的,冲刺和玩阻塞,它们工作得很好。使用 Java8 时需要小心,因为有一个默认的 common-fork/join 池,并且在那里占用线程可能会对其他用户产生影响。您始终可以使用额外的开销定义自己的 f/j 池,但至少您不会干扰使用公共池的其他人。

      你的场景看起来不错。您无需等待来自互联网的回复。试试看。如果您在停止线程时遇到困难,请查看 ForkJoinPool.ManagedBlocker 接口。使用该接口会通知 f/j 池您正在进行阻塞调用,并且框架将创建补偿线程。

      【讨论】:

        猜你喜欢
        • 2015-03-05
        • 2015-11-04
        • 2015-12-18
        • 2015-11-17
        • 1970-01-01
        • 2011-05-15
        • 1970-01-01
        • 1970-01-01
        • 2015-10-16
        相关资源
        最近更新 更多