Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 何时创建新ForkJoinPool以及何时使用CommonPool?_Java_Multithreading_Forkjoinpool - Fatal编程技术网

Java 何时创建新ForkJoinPool以及何时使用CommonPool?

Java 何时创建新ForkJoinPool以及何时使用CommonPool?,java,multithreading,forkjoinpool,Java,Multithreading,Forkjoinpool,我在阅读线程方面的内容,并学习了fork/join API 我发现,您可以使用commonPool作为管理线程的默认池来运行线程,也可以将线程提交到新创建的ForkJoinPool 据我了解,两者的区别如下: commonPool是静态创建的主池(其中一些池方法不能像关闭其他池那样正常工作),主要用于运行应用程序 default/commonPool中的并行数是核心数-1,其中新创建的池的默认并行数=核心数(或由系统属性parallelism-我忽略完全限定的系统属性键名-)指定的数字) 根

我在阅读线程方面的内容,并学习了fork/join API

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

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

  • commonPool是静态创建的主池(其中一些池方法不能像关闭其他池那样正常工作),主要用于运行应用程序
  • default/commonPool中的并行数是核心数-1,其中新创建的池的默认并行数=核心数(或由系统属性
    parallelism
    -我忽略完全限定的系统属性键名-)指定的数字)
根据文档,commonPool适合大多数用途

这一切归结为我的问题:

我应该什么时候使用公共游泳池?为什么会这样?我应该在什么时候创建新池?为什么会这样?

短篇小说 与软件工程中的大多数事情一样,答案是:“视情况而定”

使用公共池的优点 如果你看这篇精彩的文章:

根据Oracle的文档,使用预定义的公共池可以减少资源消耗,因为这不鼓励为每个任务创建单独的线程池

使用fork/join框架可以加快大型任务的处理速度, 但为了实现这一结果,应遵循一些准则:

  • 使用尽可能少的线程池——在大多数情况下,这是最好的决定 是为每个应用程序或系统使用一个线程池
  • 使用默认值 公共线程池,如果不需要特定的调优
  • 使用合理的阈值将ForkJoingTask拆分为子任务
  • 避免forkjoingtask中的任何阻塞

使用专用池的优点 然而,也有一些反对这种方法的论据:

用于复杂应用程序的专用池

在复杂应用程序中,为每个逻辑工作单元提供专用池有时是首选方法。设想一个应用程序:

  • 接收大量事件并将其分组(,可以并行完成)
  • 然后工人们做工作(,也可以并行完成)
  • 最后,一些清理人员进行一些清理(,也可以并行进行) 因此,您的应用程序有3个逻辑工作组,每个逻辑工作组可能都有自己的并行性需求。(请记住,此池已将并行性设置为计算机)

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


    其他库

    如果你的应用程序代码只有一个地方需要并行性,你不能保证某些开发人员不会拉一些第三方依赖关系,这也依赖于公共ForkJoinPool,而且你还有两个地方需要这个池。这对于您的用例来说可能是好的,但可能不是,特别是当您的默认池的并行度为4或更低时

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


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

    此外,公共forkJoinPool有一个相当非描述性的命名,因此如果您正在调试或查看日志,很可能需要筛选大量的日志

    ForkJoinPool.commonPool worker xx

    在上述情况下,将其与以下情况进行比较:

    ForkJoinPool.分组工作者xx

    ForkJoinPool.payload handler worker xx

    ForkJoinPool.cleanup worker

    因此,您可以看到,在为每个逻辑工作组使用专用的ForkJoinPool时,日志记录有一些好处


    TL;博士 使用公共ForkJoinPool对内存的影响较小,创建的资源和线程较少,垃圾收集需求也较低。然而,如上所述,这种方法对于某些用例可能是不够的

    在应用程序的每个逻辑工作单元中使用专用的ForkJoinPool可以提供更整洁的日志记录,在并行度较低的情况下(即内核不多),以及希望避免应用程序逻辑上不同部分之间的线程争用时,使用不是一个坏主意。然而,的代价是更高的cpu利用率、更高的内存开销和更多的线程创建