线程池核心线程数设为 0 会怎样?(附源码解析)

张开发
2026/4/19 20:18:23 15 分钟阅读

分享文章

线程池核心线程数设为 0 会怎样?(附源码解析)
不知道大家学习线程池时有没有这个疑问创建线程池时如果用的无界队列或者比较大的队列核心线程数设置为 0按照网上说的线程池的任务执行流程队列不满不会创建非核心线程那不炸了吗任务永远执行不了网上普遍的线程池工作流程图先说结论即使核心线程数设置为 0提交一个任务后线程池也会创建一个线程去执行。代码验证核心线程数为 0线程池中会创建一个线程任务会由这个线程顺序执行public static void main(String[] args) throws InterruptedException { // 配置核心 0最大 5存活 60 秒 ThreadPoolExecutor executor new ThreadPoolExecutor( 0, 5, 60, TimeUnit.SECONDS, new LinkedBlockingQueue(100) ); // 提交 10 个任务 for (int i 0; i 10; i) { int cur i; executor.execute(() - { System.out.println(cur 执行线程 Thread.currentThread().getName()); }); } }为了更加清楚执行过程中线程池的情况public static void main(String[] args) throws InterruptedException { // 配置核心 0最大 5存活 60 秒 ThreadPoolExecutor executor new ThreadPoolExecutor( 0, 5, 60, TimeUnit.SECONDS, new LinkedBlockingQueue(100) ); // 提交 3 个任务 for (int i 0; i 3; i) { int cur i; executor.execute(() - { System.out.println(cur 执行线程 Thread.currentThread().getName()); try { Thread.sleep(500); // 模拟任务执行时间 } catch (InterruptedException e) { throw new RuntimeException(e); } }); // 打印当前线程池状态 System.out.println( 提交任务 i 后 ); System.out.println(核心线程数 executor.getCorePoolSize()); System.out.println(最大线程数 executor.getMaximumPoolSize()); System.out.println(当前线程数 executor.getPoolSize()); System.out.println(活跃线程数 executor.getActiveCount()); System.out.println(队列大小 executor.getQueue().size()); System.out.println(完成任务数 executor.getCompletedTaskCount()); System.out.println(\n); Thread.sleep(1000); } // 等待所有任务完成 Thread.sleep(3000); System.out.println(\n 最终状态 ); System.out.println(当前线程数 executor.getPoolSize()); System.out.println(活跃线程数 executor.getActiveCount()); System.out.println(队列大小 executor.getQueue().size()); System.out.println(完成任务数 executor.getCompletedTaskCount()); }可以看出线程池中始终只有一个线程在处理任务正常情况下设置核心线程数为 2会有两个线程会并发执行。public static void main(String[] args) throws InterruptedException { // 配置核心 2最大 5存活 60 秒 ThreadPoolExecutor executor new ThreadPoolExecutor( 2, 5, 60, TimeUnit.SECONDS, new LinkedBlockingQueue(100) ); // 提交 10 个任务 for (int i 0; i 10; i) { int cur i; executor.execute(() - { System.out.println(cur 执行线程 Thread.currentThread().getName()); }); } }源码分析debug一层层扒开源码看一下整个流程。任务提交时可以看到线程池无线程走到 execute 方法里面这时可以队列中加入一个任务接着会走进workerCountOf(recheck) 0这个判断里即线程数为 0这是个兜底策略针对核心线程数为 0 的特殊情况execute源码public void execute(Runnable command) { if (command null) throw new NullPointerException(); int c ctl.get(); if (workerCountOf(c) corePoolSize) { if (addWorker(command, true)) return; c ctl.get(); } if (isRunning(c) workQueue.offer(command)) { int recheck ctl.get(); if (! isRunning(recheck) remove(command)) reject(command); else if (workerCountOf(recheck) 0) addWorker(null, false); } else if (!addWorker(command, false)) reject(command); }进入addWorker 方法就可以看到这里会创建一个线程去执行任务可以看到线程数为 1addWorker 源码private boolean addWorker(Runnable firstTask, boolean core) { retry: for (int c ctl.get();;) { // Check if queue empty only if necessary. if (runStateAtLeast(c, SHUTDOWN) (runStateAtLeast(c, STOP) || firstTask ! null || workQueue.isEmpty())) return false; for (;;) { if (workerCountOf(c) ((core ? corePoolSize : maximumPoolSize) COUNT_MASK)) return false; if (compareAndIncrementWorkerCount(c)) break retry; c ctl.get(); // Re-read ctl if (runStateAtLeast(c, SHUTDOWN)) continue retry; // else CAS failed due to workerCount change; retry inner loop } } boolean workerStarted false; boolean workerAdded false; Worker w null; try { w new Worker(firstTask); final Thread t w.thread; if (t ! null) { final ReentrantLock mainLock this.mainLock; mainLock.lock(); try { // Recheck while holding lock. // Back out on ThreadFactory failure or if // shut down before lock acquired. int c ctl.get(); if (isRunning(c) || (runStateLessThan(c, STOP) firstTask null)) { if (t.getState() ! Thread.State.NEW) throw new IllegalThreadStateException(); workers.add(w); workerAdded true; int s workers.size(); if (s largestPoolSize) largestPoolSize s; } } finally { mainLock.unlock(); } if (workerAdded) { t.start(); workerStarted true; } } } finally { if (! workerStarted) addWorkerFailed(w); } return workerStarted; }最后你以为是 bug 设计线程池的大佬早就预料到了

更多文章