在Java应用中,高并发请求会瞬间产生大量任务,如果为每个请求都创建新线程,会导致线程频繁创建销毁、上下文切换开销过大,甚至耗尽系统内存。线程池通过预先创建一定数量的线程,复用线程处理任务,能有效控制线程数量,提升系统处理高并发请求的能力。

Java线程池核心类ThreadPoolExecutor
Java通过ThreadPoolExecutor类提供自定义线程池的能力,其构造方法包含7个核心参数,开发者可以根据业务场景调整这些参数适配高并发请求处理需求。
核心参数说明
| 参数名称 | 参数作用 |
|---|---|
| corePoolSize | 核心线程数,线程池长期保持存活的线程数量,即使线程空闲也不会销毁 |
| maximumPoolSize | 最大线程数,当任务队列满了之后,线程池最多可以创建的线程数量 |
| keepAliveTime | 非核心线程的空闲存活时间,超过这个时间非核心线程会被销毁 |
| unit | keepAliveTime的时间单位 |
| workQueue | 任务队列,用于存放等待执行的任务 |
| threadFactory | 线程工厂,用于创建线程,可自定义线程名称方便排查问题 |
| handler | 拒绝策略,当任务队列满了且线程数达到最大线程数时,处理新提交任务的策略 |
自定义线程池示例
以下是一个适配普通高并发Web请求的线程池创建示例:
import java.util.concurrent.*;
public class HighConcurrencyThreadPool {
// 自定义线程工厂,设置线程名称前缀
static class CustomThreadFactory implements ThreadFactory {
private final String namePrefix;
private int threadNum = 0;
public CustomThreadFactory(String namePrefix) {
this.namePrefix = namePrefix;
}
@Override
public Thread newThread(Runnable r) {
threadNum++;
return new Thread(r, namePrefix + "-thread-" + threadNum);
}
}
public static void main(String[] args) {
// 核心线程数设置为CPU核心数的2倍,适配IO密集型高并发场景
int corePoolSize = Runtime.getRuntime().availableProcessors() * 2;
// 最大线程数设置为核心线程数的2倍
int maximumPoolSize = corePoolSize * 2;
// 非核心线程空闲存活时间60秒
long keepAliveTime = 60L;
TimeUnit unit = TimeUnit.SECONDS;
// 使用有界队列,避免任务无限堆积
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(1000);
// 自定义线程工厂
ThreadFactory threadFactory = new CustomThreadFactory("high-concurrency");
// 拒绝策略:当任务无法处理时,由提交任务的线程执行该任务
RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
// 创建线程池
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
workQueue,
threadFactory,
handler
);
// 模拟提交100个高并发请求任务
for (int i = 0; i < 100; i++) {
int taskId = i;
threadPool.submit(() -> {
// 模拟处理请求的逻辑,比如调用业务接口、查询数据库等
System.out.println("线程" + Thread.currentThread().getName() + "处理任务" + taskId);
try {
// 模拟请求处理耗时
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
// 关闭线程池,不再接受新任务,等待已有任务执行完成
threadPool.shutdown();
}
}
高并发场景下的线程池参数调整建议
不同类型的请求场景需要适配不同的线程池参数:
- 如果是CPU密集型请求,核心线程数可以设置为CPU核心数+1,避免过多线程导致上下文切换开销过大
- 如果是IO密集型请求,核心线程数可以设置为CPU核心数的2到4倍,因为线程在IO等待时会释放CPU,可复用更多线程处理请求
- 任务队列建议使用有界队列,比如
ArrayBlockingQueue,避免无界队列导致任务无限堆积,最终引发内存溢出 - 拒绝策略需要根据业务场景选择,比如重要请求可以使用
CallerRunsPolicy让提交任务的线程执行,非重要请求可以使用DiscardPolicy直接丢弃
线程池监控与优化
处理高并发请求时,需要监控线程池的运行状态,及时调整参数:
- 可以通过
ThreadPoolExecutor的getActiveCount()方法获取当前活跃线程数 - 通过
getTaskCount()获取已提交的任务总数 - 通过
getCompletedTaskCount()获取已完成的任务总数 - 当活跃线程数长期接近最大线程数、任务队列长期满时,需要适当调大核心线程数和最大线程数,或者优化请求处理逻辑
常见注意事项
不要使用Executors工具类提供的快捷方法创建线程池,比如newFixedThreadPool、newCachedThreadPool,这些方法要么使用无界队列要么最大线程数无限制,在高并发场景下容易引发资源问题。
另外,线程池使用完成后要及时调用shutdown()方法关闭,避免线程一直存活占用系统资源。如果是Web应用,可以将线程池作为全局单例对象,在应用启动时创建,应用关闭时销毁。
Java线程池高并发ThreadPoolExecutor修改时间:2026-07-02 16:36:26