🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 线程池入门到精通 ## 什么是线程池 * 复用创建好的线程,节约创建和销毁的时间。 * 需要使用线程时,就从池子里拿一个空闲的线程,完成工作后,归还线程给线程池。 ## 线程池工作原理 ![](https://img.kancloud.cn/ca/63/ca63d4ed125abe5e16408822cc359c82_1576x1498.png) ## 线程池工作流程 ![](https://img.kancloud.cn/2f/b9/2fb9bccd4a105343413fd5d9de66744d_1358x1226.png) ## 线程池生命周期及扩展点 ![](https://img.kancloud.cn/42/85/42857a031ae9ba403492fdce48d56073_454x1312.png) ## 线程池参数 ![](https://img.kancloud.cn/2f/de/2fde29f17f5e5145a0d45191ff52817a_1610x1100.png) ## JDK提供的线程池 ![](https://img.kancloud.cn/9a/80/9a80163ec83ebcd3107193f670cc0474_1612x1112.png) ## 线程池常见阻塞队列 ![](https://img.kancloud.cn/6c/b0/6cb0bb59ef589dd80a25021eb9b2a8ea_1212x828.png) ## 线程池内置拒绝策略 ![](https://img.kancloud.cn/42/d9/42d9feb65d859e84c316c2e5daf3841f_884x698.png) ## 线程池核心线程数设置 ![](https://img.kancloud.cn/f8/17/f817f94112a2e027ec33f658cff9fb43_1532x694.png) ## Fork/Join框架 ### 执行逻辑 ![](https://img.kancloud.cn/69/1f/691f88d48cbfccf55b2eef1f80579770_1668x804.png) ### 窃取原理 ![](https://img.kancloud.cn/4e/f7/4ef79ee39d07362349edad71e6791ecf_500x796.png) ### 任务类图 ![](https://img.kancloud.cn/71/59/715983070eb632c6327f2000c0fefb30_986x560.png) ### 例子 求开始数到结束数的和。 ~~~ package org.mango.demo.mt.thread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.*; /** * 递归任务,带返回值的 * @Author: mango * @Date: 2022/6/27 10:18 下午 */ public class SumTask extends RecursiveTask<Long> implements Callable<Long> { // 临界值 private static final int THRESHOLD = 10000; private long start; private long end; public SumTask(long start,long end){ this.start = start; this.end = end; } @Override protected Long compute() { long sum = 0L; boolean canSum = (end-start) < THRESHOLD; if(canSum){ for(long i=start;i<=end;i++){ sum += i; } }else{ // 分成100个小任务 int count = 100; long step = (end-start)/count; List<SumTask> sumTasks = new ArrayList<>(); // 游标 long cursor = start; for(int i=0;i<count;i++){ long theEnd = cursor + step; if(theEnd > end){ theEnd = end; } SumTask sumTask = new SumTask(cursor,theEnd); // 游标下移动 cursor += step + 1; // 将任务加入集合,并开启子任务 sumTasks.add(sumTask); sumTask.fork(); } // 合并子任务结果 for (SumTask sumTask : sumTasks){ sum += sumTask.join(); } } return sum; } public static void main(String[] args) throws ExecutionException, InterruptedException { ForkJoinPool forkJoinPool = new ForkJoinPool(); SumTask sumTask = new SumTask(1,123456789L); Long result = forkJoinPool.invoke(sumTask); System.out.println("结果为:"+result); // ForkJoinTask<Long> forkJoinTask = forkJoinPool.submit(sumTask); // try { // Long result2 = forkJoinTask.get(); // } catch (InterruptedException e) { // e.printStackTrace(); // } catch (ExecutionException e) { // e.printStackTrace(); // } ExecutorService executorService = Executors.newWorkStealingPool(); Future<Long> t = executorService.submit(sumTask); Long result2 = t.get(); System.out.println(result2); } @Override public Long call() throws Exception { return compute(); } } ~~~ ## 参考文档 * https://www.zhihu.com/question/41134816 * 书籍:葛一鸣 *《Java高并发程序设计第二版》