首页 游戏 软件 资讯 排行榜 专题
首页
编程语言
怎么区分 Stream 流的并行处理 parallel() 与普通处理在底层线程池(ForkJoinPool)的共用

怎么区分 Stream 流的并行处理 parallel() 与普通处理在底层线程池(ForkJoinPool)的共用

热心网友
56
转载
2026-04-29

怎么区分 Stream 流的并行处理 parallel() 与普通处理在底层线程池(ForkJoinPool)的共用

怎么区分 Stream 流的并行处理 parallel() 与普通处理在底层线程池(ForkJoinPool)的共用

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

简单来说,并行流的 parallel() 并不创建新线程池,而是直接复用 JVM 全局共享的 ForkJoinPool.commonPool()。普通流(stream())则完全是另一回事——它只在当前调用线程中顺序执行,根本不涉及任何线程池和并发调度。

parallel() 的线程池来源是固定的

所有未显式指定线程池的并行流,底层都走同一个 ForkJoinPool 实例:ForkJoinPool.commonPool()。这里有个关键点:这个池子不是每次调用时新建的,而是 JVM 启动时初始化一次的静态共享池。

  • 它的默认并行度计算公式是:Runtime.getRuntime().a vailableProcessors() - 1。举个例子,在一台8核的机器上,默认就是7个并行线程。
  • 这个默认值是可以提前配置的,通过系统属性就能调整:System.setProperty("ja va.util.concurrent.ForkJoinPool.common.parallelism", "12");
  • 需要注意的是,这个设置是全局性的。它影响的不仅仅是 parallelStream,所有使用 commonPool 的地方都会生效,比如 ForkJoinTask.invoke()CompletableFuture 的默认异步执行。

普通流 stream() 完全不依赖线程池

list.stream().filter(...).map(...) 这样的普通流操作,整个链路都在当前线程内完成。没有任务提交、没有工作窃取、也没有线程调度的开销。它的执行模型和传统的 for 循环一样,是纯同步、单线程且行为可预测的。

  • 它不会触发任何 ForkJoinPool 的初始化。
  • 不会占用 commonPool 的线程或队列资源。
  • 即使在多线程环境中调用,每个线程也只是各自执行自己的 stream 操作,彼此完全隔离。

如何验证是否共用同一个 commonPool

想亲眼看看是不是真的共用一个池子?可以通过打印线程名或检查池状态来验证:

  • 在 parallelStream 操作中打印线程名:
    .forEach(x -> System.out.println(Thread.currentThread().getName()))
    你会看到输出中包含类似 ForkJoinPool.commonPool-worker-1 这样的名称。
  • 对比调用 ForkJoinPool.commonPool().toString()list.parallelStream().count() 前后,池子的 activeThreadCount 或 poolSize 等状态值会发生变化。
  • 最直接的证据是,当多个并行流同时运行时,它们的子任务会竞争同一组 worker 线程,而不是各自独占一套资源。

注意:sequential() 不会切换线程池

这里有个容易混淆的地方:调用 .parallel().sequential() 只是让后续操作退回到单线程顺序执行模式。但是,整个流可能已经在 commonPool 中启动过 fork/join 分支了。这个方法并不会释放线程,也不会切换到其他池子——它的作用仅仅是“不再进行并行调度”,而实际执行任务的线程,很可能还是 commonPool 里的某个 worker。

来源:https://www.php.cn/faq/2387677.html
免责声明: 游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关攻略

怎么区分 Stream 流的并行处理 parallel() 与普通处理在底层线程池(ForkJoinPool)的共用
编程语言
怎么区分 Stream 流的并行处理 parallel() 与普通处理在底层线程池(ForkJoinPool)的共用

怎么区分 Stream 流的并行处理 parallel() 与普通处理在底层线程池(ForkJoinPool)的共用 简单来说,并行流的 parallel() 并不创建新线程池,而是直接复用 JVM 全局共享的 ForkJoinPool commonPool()。普通流(stream())则完全是另

热心网友
04.29
怎么利用 IntStream.summaryStatistics() 一次性获取整数序列的均值、极值与总和
编程语言
怎么利用 IntStream.summaryStatistics() 一次性获取整数序列的均值、极值与总和

怎么利用 IntStream summaryStatistics() 一次性获取整数序列的均值、极值与总和 在Ja va的流式编程中,IntStream summaryStatistics() 方法堪称一个“统计多面手”。它返回一个包含计数、总和、最小值、最大值和平均值的对象。这里有个关键细节:对于

热心网友
04.29
Elgato推出标志蓝紫版Stream Deck Mini直播控制器,专为Discord优化
科技数码
Elgato推出标志蓝紫版Stream Deck Mini直播控制器,专为Discord优化

11 月 11 日消息,海盗船旗下 Elgato 德国当地时间 10 日宣布推出 Discord 特别版 Stream Deck Mini。这款拥有六个可自定义 LCD 按键的直播控台采用了 Di

热心网友
11.27

最新APP

宝宝过生日
宝宝过生日
应用辅助 04-07
台球世界
台球世界
体育竞技 04-07
解绳子
解绳子
休闲益智 04-07
骑兵冲突
骑兵冲突
棋牌策略 04-07
三国真龙传
三国真龙传
角色扮演 04-07

热门推荐

MongoDB 3.6旧版本如何平滑迁移GridFS数据_使用mongodump与mongorestore
数据库
MongoDB 3.6旧版本如何平滑迁移GridFS数据_使用mongodump与mongorestore

MongoDB 3 6旧版本如何平滑迁移GridFS数据 在MongoDB 3 6版本中,使用mongodump进行数据备份时,默认会忽略GridFS存储所使用的fs files和fs chunks集合,因为它们被系统视为内部命名空间。为确保GridFS文件数据的完整迁移,必须显式指定导出这两个集合

热心网友
04.29
Redis如何批量删除特定前缀的Key_使用Lua脚本避免阻塞主线程
数据库
Redis如何批量删除特定前缀的Key_使用Lua脚本避免阻塞主线程

生产环境禁用 KEYS+DEL,因其会阻塞 Redis 主线程;应使用带游标和分批的 SCAN+DEL Lua 脚本或 Ja va 中通过 RedisConnection 执行 SCAN 迭代删除,避免连接泄漏。 直接使用 KEYS 配合 DEL 来批量删除特定前缀的 Key,听起来很直接,对吧?但

热心网友
04.29
Redis为什么会出现内存泄漏的假象_排查Lua脚本中未设置过期的临时变量
数据库
Redis为什么会出现内存泄漏的假象_排查Lua脚本中未设置过期的临时变量

Redis为什么会出现内存泄漏的假象?排查Lua脚本中未设置过期的临时变量 Redis内存持续上涨可能源于Lua脚本中未设置过期时间的临时键,如set、hset、zadd写入后遗漏expire,导致“孤儿键”累积;需用redis-cli --scan结合object freq和ttl定位,并按业务语

热心网友
04.29
如何用SQL实现多级分组的排名统计_窗口函数扩展
数据库
如何用SQL实现多级分组的排名统计_窗口函数扩展

多级分组排名应选rank()或dense_rank()而非row_number():rank()跳过重复名次,dense_rank()连续编号;必须配合PARTITION BY和ORDER BY,且WHERE筛选需用子查询避免破坏分组。 rank() 和 dense_rank() 在多级分组中行为差

热心网友
04.29
Redis如何实现基于发布订阅的配置热更新_发布配置变更通知触发服务重载
数据库
Redis如何实现基于发布订阅的配置热更新_发布配置变更通知触发服务重载

Redis如何实现基于发布订阅的配置热更新 Redis Pub Sub 能否可靠用于配置热更新? 直接拿来用?恐怕不行。Redis 的 PUBLISH SUBSCRIBE 本质上是一种“即发即弃”的模型:消息不持久、没有确认机制、订阅者离线期间的消息会彻底丢失。想象一下,你的服务因为重启或者网络短暂

热心网友
04.29