jok*_*ker 6 java multithreading forkjoinpool
我正在阅读线程并了解 fork/join API。
我发现您可以使用 commonPool 作为管理线程的默认池运行线程,或者我可以将线程提交到新创建的 ForkJoinPool。
两者之间的区别如下,据我所知:
parallelism
- 我忽略了完全限定的系统属性键名-)。根据文档,commonPool 适用于大多数用途。
这一切都归结为我的问题:
什么时候应该使用公共池?为什么会这样?我应该什么时候创建一个新池?为什么会这样?
答案,就像在软件工程中的大多数事情,就是:“这取决于”。
如果你看这篇精彩的文章:
根据 Oracle 的文档,使用预定义的公共池会减少资源消耗,因为这会阻止为每个任务创建单独的线程池。
和
使用 fork/join 框架可以加快大型任务的处理速度,但要实现此结果,应遵循一些准则:
- 使用尽可能少的线程池——在大多数情况下,最好的决定是为每个应用程序或系统使用一个线程池
- 使用默认的公共线程池,如果不需要特殊调优
- 使用合理的阈值将 ForkJoingTask 拆分为子任务
- 避免 ForkJoingTasks 中的任何阻塞
然而,也有一些争论反对采取这一方式:
复杂应用的专用池
在复杂的应用程序中,每个逻辑工作单元都有一个专用池有时是首选方法。想象一个应用程序:
因此,您的应用程序有 3 个逻辑工作组,每个工作组可能都有自己的并行需求。(请记住,这个池的并行度在大多数机器上设置得相当低)
最好不要踩到对方的脚趾,对吧?请注意,这可以扩展到某个级别,建议为每个工作单元提供单独的微服务,但是如果由于某种原因您还没有在那里,那么每个逻辑工作单元的专用 forkJoinPool不是一个坏主意。
其他图书馆
如果您的应用程序的代码只有一个地方需要并行性,则您无法保证某些开发人员不会拉一些同样依赖于公共 ForkJoinPool 的 3-rd 方依赖项,并且您仍然有两个地方可以使用此池有需求。这对于您的用例来说可能没问题,也可能不是,特别是如果您的默认池的并行度为 4 或更低。
想象一下当您的应用程序关键代码(例如事件处理或将数据保存到数据库)必须与某个库竞争公共池时的情况,该库将日志并行导出到某个日志接收器。
专用的 ForkJoinPool 使日志记录更整洁
此外,常见的 forkJoinPool 具有相当非描述性的命名,因此如果您正在调试或查看日志,您可能需要筛选大量
ForkJoinPool.commonPool-worker-xx
在上述情况下,将其与:
ForkJoinPool.grouping-worker-xx
ForkJoinPool.payload-handler-worker-xx
ForkJoinPool.cleanup-worker
因此,您可以看到当每个逻辑工作组使用专用的 ForkJoinPool 时,日志记录清洁有一些好处。
使用通用的 ForkJoinPool具有更低的内存影响、更少的资源和线程创建以及更低的垃圾收集需求。但是,如上所述,对于某些用例,这种方法可能是不够的。
在您的应用程序中为每个逻辑工作单元使用专用的 ForkJoinPool可提供更整洁的日志记录,当您的并行度级别较低(即内核不多)时,以及当您想避免应用程序逻辑上不同部分之间的线程争用时,使用这不是一个坏主意. 然而,这是以更高的 CPU 利用率、更高的内存开销和更多线程创建为代价的。
归档时间: |
|
查看次数: |
1078 次 |
最近记录: |