forkjoinpool通过工作窃取算法避免cpu核心空闲:空闲线程从其他线程双端队列尾部窃取任务,本地lifo执行、窃取fifo取尾,头尾分离降低竞争;默认并行度为cpu核数减1以平衡调度开销;仅在任务可分、粒度适中(如耗时>10μs)、无io/锁时有效。

它靠的是不让任何 CPU 核心空闲,把“等任务”变成“找任务”。传统线程池里,一个线程干完活就停着,其他线程还在忙——那几颗核心就白白闲置。ForkJoinPool 不让这事发生。
每个线程都有自己的双端队列
线程执行任务时,从自己队列的头部取(LIFO),最近 fork 的子任务优先跑,缓存友好、局部性好;而别的线程来“偷”时,只许从队列的尾部拿(FIFO),拿走最早入队、等得最久的任务。头和尾由不同线程操作,天然避开锁竞争和缓存伪共享。
空闲线程主动出击,不是干等
当某个线程把自己的队列掏空了,它不会挂起或阻塞,而是随机扫描其他线程的队列,悄悄从尾部拿一个任务过来执行。这个过程不需要协调、不加锁,开销低,还能立刻填满 CPU 时间片。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
并行度设置贴近硬件实际
默认公共池的并行度通常是 CPU 核数减 1,原因很实在:
- 留一个核给主线程或系统调度,避免因抢占引发延迟抖动
- 分治任务常有较深调用栈,线程太多反而增加上下文切换和队列管理负担
- 实测表明,并行度超过物理核数后,计算密集型任务性能往往下降
任务拆分要“刚刚好”
工作窃取不是万能的,它只在任务可拆、粒度合适时才真正起效:
- 阈值设太大:任务没机会 fork,全在线程本地顺序执行,根本没东西可偷
- 阈值设太小:fork/join 本身开销(对象创建、队列插入、同步)盖过计算收益
- 子任务平均耗时低于 10μs:偷一次任务的代价可能比执行还高
- 任务含 IO 或锁:该用 ThreadPoolExecutor,ForkJoin 不适合
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










