起因最近针对线程池的核心线程数设置多少与同事发生了一些歧义我的理论依据是大厂面试中面试题和标准答案曾经被虐过CPU密集型设置CPU核心数 1IO密集型CPU核心数 * 2可以远大于核心数。其他人说实际开发中并没有人会在意这些设置多少无所谓我觉得这实在是无法接受。于是我做了一波测试分别针对CPU密集型和IO密集型来看核心线程数和最大线程数对执行时间的影响。最终结论但很多面试题中说的“CPU密集型核心线程数过大超过CPU核心数那么执行时间反而会更久”。其实是不对的应该是CPU密集型核心线程数过大超过CPU核心数那么执行时间可能会出现波动较大的情况不稳定原因可能是GC / JIT / cache / context switch。过程结论CPU密集型任务结论是- 线程上下文切换造成的开销其实并没有想象中那么大。- CPU密集型耗费时间情况线程数 核心数执行速度 吞吐能力线性上升线程数 ≈ 核心数执行速度 达到峰值最快线程数 核心数出现上下文切换 cache miss 调度竞争执行速度 吞吐能力进入瓶颈不会有显著提升出现吞吐能力的抖动不稳定可能会出现大于1.5倍~2倍的平均执行速度猜测不稳定因素GC / JIT / cache / context switch实验参数- 核心线程数和最大线程数都是从1~300变化不同的线程数执行10次子线程任务。- 每个子线程执行200_000_000L次Math.sqrt(i)。IO密集型任务结论是- 线程上下文切换造成的开销其实并没有想象中那么大。- 线程越大→ 性能快速提升 → 达到平台期 → 不再变化。实验参数- 核心线程数和最大线程数都是从1~300变化不同的线程数执行10次子线程任务。- 每个子线程执行Thread.sleep(200)代码package com.luology.test.test; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class Test { public static void main(String[] args) throws Exception { int cpu Runtime.getRuntime().availableProcessors(); System.out.println(CPU核心数 cpu); for (int threadNum 1; threadNum 300; threadNum) { test(threadNum); } } private static void test(int threadNum) throws Exception { ExecutorService pool Executors.newFixedThreadPool(threadNum); long start System.currentTimeMillis(); ListFutureLong futures new ArrayList(); for (int i 0; i 10; i) { futures.add(pool.submit( new CpuTask(100000) )); } for (FutureLong future : futures) { future.get(); } long end System.currentTimeMillis(); pool.shutdown(); System.out.printf( 线程数%d耗时%dms%n, threadNum, end - start ); } }package com.luology.test.test; import java.util.concurrent.Callable; public class CpuTask implements CallableLong { private final int num; public CpuTask(int num) { this.num num; } Override public Long call() throws InterruptedException { // ### CPU密集型任务 // double sum 0; // // for (long i 0; i 200_000_000L; i) { // sum Math.sqrt(i); // } // // return (long) sum; // ### IO 密集型任务 Thread.sleep(200); return 1L; } }