Java学习随笔:线程池的核心参数到底在管什么(2026-09-20)
学习并发编程的时候,线程池是一个绕不开的话题。刚开始我以为它只是“预先创建一批线程,有任务就拿来用”这么简单,直到真正去读 ThreadPoolExecutor 的源码和文档,才发现它的核心其实是一组互相配合的参数。理解这些参数各自管什么,比记住“用线程池比直接 new Thread 好”这句话要有用得多。
线程池最关键的几个参数是核心线程数、最大线程数、空闲线程存活时间、时间单位、任务队列、线程工厂和拒绝策略。它们共同决定了任务提交之后会怎么被处理。当一个新任务提交进来时,线程池并不是马上创建新线程,而是先判断当前正在运行的线程数有没有达到核心线程数。如果没有达到,就直接新建一个线程来执行这个任务;如果已经达到,就把任务放进任务队列里排队等待。
如果任务队列满了,线程池才会继续创建新线程,直到线程总数达到最大线程数。这里有一个很容易记反的地方:很多人以为“只要任务多就先加线程”,实际上线程池的顺序是先占满核心线程、再填满队列、最后才把线程数扩展到最大值。所以任务队列的类型会直接影响线程池的行为:用有界队列,队列满了才会扩容到最大线程数;用无界队列,队列几乎不会被填满,最大线程数这个参数就形同虚设。
当线程数超过核心线程数、又长时间没有新任务时,多出来的线程会在空闲超过存活时间后被回收,让线程池回落到核心线程数的规模。这一条配合前两个参数,构成了线程池“伸”和“缩”的能力,也解释了为什么空闲时间这个看似不起眼的参数必须和最大线程数放在一起看。
如果队列满了、线程数也到达了最大值,新提交的任务就会交给拒绝策略处理。常见的策略有直接抛出异常、让提交任务的线程自己执行、丢弃当前任务、丢弃队列里最早的任务等。选哪一种,要看业务能不能接受任务丢失、能不能接受提交方被阻塞,这里没有标准答案,只有权衡。
线程工厂则决定了线程怎么被创建,比如线程名、优先级、是否为守护线程。给线程起一个有业务含义的名字,在排查线上问题时非常关键,因为线程转储里的名字往往就是定位问题的第一线索。
这次学习让我明白,线程池并不是一个“配好就能用”的组件,而是一组需要结合业务去权衡的参数。任务是什么类型、能不能容忍排队、失败了要不要重试,都会影响参数的选择。把每个参数的职责想清楚,再回头配置核心线程数和队列容量,心里才会有底。

浙公网安备 33010602011771号