Java 何时创建新ForkJoinPool以及何时使用CommonPool?
我在阅读线程方面的内容,并学习了fork/join API 我发现,您可以使用commonPool作为管理线程的默认池来运行线程,也可以将线程提交到新创建的ForkJoinPool 据我了解,两者的区别如下:Java 何时创建新ForkJoinPool以及何时使用CommonPool?,java,multithreading,forkjoinpool,Java,Multithreading,Forkjoinpool,我在阅读线程方面的内容,并学习了fork/join API 我发现,您可以使用commonPool作为管理线程的默认池来运行线程,也可以将线程提交到新创建的ForkJoinPool 据我了解,两者的区别如下: commonPool是静态创建的主池(其中一些池方法不能像关闭其他池那样正常工作),主要用于运行应用程序 default/commonPool中的并行数是核心数-1,其中新创建的池的默认并行数=核心数(或由系统属性parallelism-我忽略完全限定的系统属性键名-)指定的数字) 根
- commonPool是静态创建的主池(其中一些池方法不能像关闭其他池那样正常工作),主要用于运行应用程序
- default/commonPool中的并行数是核心数-1,其中新创建的池的默认并行数=核心数(或由系统属性
-我忽略完全限定的系统属性键名-)指定的数字)parallelism
- 使用尽可能少的线程池——在大多数情况下,这是最好的决定 是为每个应用程序或系统使用一个线程池
- 使用默认值 公共线程池,如果不需要特定的调优
- 使用合理的阈值将ForkJoingTask拆分为子任务
- 避免forkjoingtask中的任何阻塞
使用专用池的优点 然而,也有一些反对这种方法的论据: 用于复杂应用程序的专用池 在复杂应用程序中,为每个逻辑工作单元提供专用池有时是首选方法。设想一个应用程序:
其他库 如果你的应用程序代码只有一个地方需要并行性,你不能保证某些开发人员不会拉一些第三方依赖关系,这也依赖于公共ForkJoinPool,而且你还有两个地方需要这个池。这对于您的用例来说可能是好的,但可能不是,特别是当您的默认池的并行度为4或更低时 想象一下,当您的应用程序关键代码(例如事件处理或将数据保存到数据库)必须与某个并行将日志导出到某个日志接收器的库竞争公共池时的情况
专用ForkJoinPool使日志记录更加整洁 此外,公共forkJoinPool有一个相当非描述性的命名,因此如果您正在调试或查看日志,很可能需要筛选大量的日志
ForkJoinPool.commonPool worker xx
在上述情况下,将其与以下情况进行比较:
ForkJoinPool.分组工作者xx
ForkJoinPool.payload handler worker xx
ForkJoinPool.cleanup worker
因此,您可以看到,在为每个逻辑工作组使用专用的ForkJoinPool时,日志记录有一些好处
TL;博士 使用公共ForkJoinPool对内存的影响较小,创建的资源和线程较少,垃圾收集需求也较低。然而,如上所述,这种方法对于某些用例可能是不够的 在应用程序的每个逻辑工作单元中使用专用的ForkJoinPool可以提供更整洁的日志记录,在并行度较低的情况下(即内核不多),以及希望避免应用程序逻辑上不同部分之间的线程争用时,使用不是一个坏主意。然而,的代价是更高的cpu利用率、更高的内存开销和更多的线程创建