工作窃取算法的核心是“主动补位”式负载均衡:每个线程独占双端队列,本地LIFO执行保局部性,空闲线程FIFO窃取他人队列尾部任务,随机选择目标以零冲突实现CPU零空转。

工作窃取算法的核心精髓,不是“强行分担”,而是“主动补位”——它把线程从被动等待者,变成负载均衡的协作者。
每个线程自带“责任田”,但不画地为牢
传统线程池里,所有线程争抢同一块“公共田地”(全局队列),容易卡在锁上;而工作窃取给每个线程划一块专属“责任田”(本地双端队列)。线程默认只耕自己的田,开销极低、无锁、缓存友好。但这块田不是封闭的:当某线程提前收工,它不会原地待命,而是转身走向别人尚未收割的田埂边,从尾部悄悄拿走一个任务——这个动作不打断原线程耕作,也不需要对方同意,靠的是队列结构设计的天然隔离。
“窃取”背后是精巧的分工协议
关键不在“偷”,而在“怎么偷不打架”:
- 自己干活走头部(top),LIFO顺序:刚 fork 出的子任务放队尾,自己立刻从头取最新任务,保持计算局部性,栈帧复用率高
- 别人来偷走尾部(base),FIFO顺序:拿走最早入队、等待最久的任务,降低整体响应延迟;且头尾分离,双方操作物理位置不同,几乎零 CAS 冲突
- 随机选目标,不盯死一个:空闲线程不是挨个轮询,而是随机挑一个兄弟队列尝试窃取,避免形成热点竞争或饿死现象
它解决的从来不是单任务快慢,而是系统吞吐的浪费
工作窃取不加速某个具体任务,它消灭的是“CPU空转时间”。比如 8 核机器跑 100 个不均等任务:可能 3 个核干了 90% 的活,其余 5 个核在等。工作窃取让那 5 个空闲核自动介入,把重载核队列尾部积压的任务分走——不是抢功,是止损。最终效果是:总耗时由最慢的那个线程决定,被显著拉低。
适用有边界,不是万能钥匙
这套机制高效的前提很明确:
- 任务得能递归拆分(如遍历树、归并排序、矩阵分块)
- 不能含阻塞操作(如 IO、synchronized、sleep),否则“窃取者”也会被卡住,反而拖累全局
- 任务粒度要适中:太粗,没机会窃取;太细,fork/join 调度开销反超收益
本质上,它是为“可分解、纯计算、非阻塞”的场景量身定制的动态负载调节器。

















