知识卡片
工作窃取补负载
内容
ForkJoinPool 里每个工作线程有自己的内部双端队列存放子任务。多个队列并行工作容易分配不均,工作窃取算法让空闲线程主动扫描别的线程队列,把任务”偷”过来执行。关键优化:自己队列用 LIFO(从头取),窃取别人队列用 FIFO(从尾取),两端操作互不冲突。适合递归拆分的 CPU 任务,和 [[按任务类型配线程]] 一样要警惕慢速阻塞操作混入子任务。
参考来源
- 位置:《Java高并发核心编程.卷2,多线程、锁、JMM、JUC、高并发设计模式》第8章《高并发设计模式》8.3.5节《工作窃取算法》(源文件:_epub-src/OEBPS/Text/chapter272.xhtml)
- 结论依据:原文说明“工作窃取算法的核心思想是:工作线程自己的活干完了之后,会去看看别人有没有没干完的活,如果有就拿过来帮忙干……每个线程拥有一个双端队列(本地队列)……当自己的队列没有任务时,可以从其他线程的任务队列中获得一个任务继续执行”,并给出“在线程自己的本地队列采取LIFO(后进先出)策略,窃取其他任务队列的任务时采用FIFO(先进先出)策略”的优化,因此推出本卡结论。
- 原始内容:工作窃取算法的核心思想是:工作线程自己的活干完了之后,会去看看别人有没有没干完的活,如果有就拿过来帮忙干……在线程自己的本地队列采取LIFO(后进先出)策略,窃取其他任务队列的任务时采用FIFO(先进先出)策略。简单来说,获取自己队列的任务时从头开始,窃取其他队列的任务时从尾开始。