贝利信息

Java并发编程中的Executor框架与线程池

日期:2026-01-09 00:00 / 作者:P粉602998670
直接new Thread()不适合高并发场景,因频繁创建销毁线程导致栈内存分配、GC压力、调度竞争及OS线程耗尽;Executor框架通过复用线程、统一管理生命周期、解耦任务提交与执行来优化。

为什么直接 new Thread() 不适合高并发场景

频繁创建和销毁线程会带来显著的系统开销:JVM 需要分配栈内存、触发 GC、参与线程调度竞争。在 QPS 较高的服务中,new Thread(runnable).start() 很快会耗尽 OS 线程资源(Linux 默认每进程约 1024 个线程),抛出 java.lang.OutOfMemoryError: unable to create new native thread

Executor 框架通过复用线程、统一管理生命周期、解耦任务提交与执行,把“怎么跑”交给线程池,“跑什么”由业务代码决定。

ThreadPoolExecutor 的几个关键参数怎么设才合理

核心不是背参数名,而是理解它们如何协同影响吞吐与稳定性。以 Web 请求处理为例:

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    4,           // corePoolSize
    8,

// maximumPoolSize 60L, // keepAliveTime TimeUnit.SECONDS, new ArrayBlockingQueue(100), new ThreadPoolExecutor.CallerRunsPolicy() );

submit() 和 execute() 的区别不只是返回值

execute(Runnable)Executor 接口方法,只负责提交,不关心结果;submit()ExecutorService 扩展方法,支持获取执行结果和异常。

线程池 shutdown() 和 shutdownNow() 到底停不停得干净

两者都不保证立即终止所有线程,只是改变线程池状态并尝试中断正在运行的任务。

实际关闭流程建议加超时等待:

executor.shutdown();
try {
    if (!executor.awaitTermination(30, TimeUnit.SECONDS)) {
        executor.shutdownNow();
        if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
            System.err.println("Pool did not terminate");
        }
    }
} catch (InterruptedException e) {
    executor.shutdownNow();
    Thread.currentThread().interrupt();
}

线程池的边界往往藏在 shutdown 逻辑里——没等完就退出、没处理中断、没清理资源,都会让应用在重启或降级时留下残留线程。