在 Java 并发编程中,直接创建和管理线程的成本较高,频繁创建线程会带来 性能开销 和 资源浪费。
线程池(ThreadPool) 的作用:
Java 线程池的主要组件如下:
组件 | 作用 |
---|---|
核心线程数(corePoolSize) | 线程池保持存活的最小线程数 |
最大线程数(maximumPoolSize) | 线程池可创建的最大线程数 |
任务队列(workQueue) | 存放等待执行的任务 |
线程工厂(ThreadFactory) | 负责创建新线程 |
拒绝策略(RejectedExecutionHandler) | 线程池已满时的处理策略 |
Executors
(不推荐)Java 提供了 Executors
工具类来创建线程池:
ExecutorService executorService = Executors.newFixedThreadPool(5);
为什么不推荐?
newFixedThreadPool()
采用 无界任务队列,可能导致 OOM。newCachedThreadPool()
允许线程无限增长,可能造成 CPU 资源耗尽。ThreadPoolExecutor
建议手动创建线程池,控制线程数和队列大小:
ExecutorService threadPool = new ThreadPoolExecutor(
5, // 核心线程数
10, // 最大线程数
60, // 空闲线程存活时间
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(1000), // 任务队列
Executors.defaultThreadFactory(), // 线程工厂
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
);
当线程池已满,任务无法提交时,Java 提供了 4 种拒绝策略:
策略 | 说明 |
---|---|
AbortPolicy |
直接抛出 RejectedExecutionException |
CallerRunsPolicy |
调用线程执行任务,降低提交速度 |
DiscardPolicy |
丢弃任务,不抛异常 |
DiscardOldestPolicy |
丢弃最老的任务,尝试提交新任务 |
execute()
或 submit()
。corePoolSize
,创建新线程执行任务。corePoolSize
,任务进入 workQueue
等待。maximumPoolSize
,创建新线程处理任务。maximumPoolSize
且队列已满,则执行拒绝策略。Java 提供了 4 种常见线程池:
线程池 | 特点 | 适用场景 |
---|---|---|
FixedThreadPool(n) |
固定数量线程池 | CPU 密集型任务 |
CachedThreadPool() |
无限增长线程池 | 短时间高并发任务 |
SingleThreadExecutor() |
单线程池 | 串行任务 |
ScheduledThreadPool(n) |
定时任务线程池 | 周期任务 |
使用 shutdown()
优雅关闭 线程池:
threadPool.shutdown();
如果需要 强制停止:
threadPool.shutdownNow();
示例获取 CPU 核心数:
int coreCount = Runtime.getRuntime().availableProcessors();
import java.util.concurrent.*;
public class ThreadPoolExample {
public static void main(String[] args) {
ExecutorService threadPool = new ThreadPoolExecutor(
2, 5, 10,
TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));
for (int i = 1; i <= 10; i++) {
int taskId = i;
threadPool.execute(() -> {
System.out.println(Thread.currentThread().getName() + " 执行任务 " + taskId);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
threadPool.shutdown();
}
}
pool-1-thread-1 执行任务 1
pool-1-thread-2 执行任务 2
pool-1-thread-1 执行任务 3
pool-1-thread-2 执行任务 4
...
Executors
创建线程池?Executors.newFixedThreadPool()
→ 队列长度无限,可能导致 OOM。Executors.newCachedThreadPool()
→ 线程数无限,可能导致 CPU 过载。根据 任务类型 和 CPU 资源 动态调整:
int coreCount = Runtime.getRuntime().availableProcessors();
ExecutorService threadPool = new ThreadPoolExecutor(
coreCount, coreCount * 2,
60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100));
✅ 线程池是 Java 并发编程的核心组件
✅ 选择 合适的线程池,避免 OOM 和 CPU 过载
✅ 手动创建 ThreadPoolExecutor
,控制任务队列和线程数
✅ 合理配置拒绝策略,确保任务不被丢弃
✅ 优雅关闭线程池,防止资源泄露
掌握线程池,优化并发性能,让你的 Java 应用飞起来!