线程池
2025年12月4日大约 2 分钟
线程池
- 线程池是一种管理和复用线程的机制,可以提高多线程程序的性能和资源利用率。
- 如果不使用线程池:每次需要执行任务时都要创建一个新的线程,频繁的创建和销毁线程会带来较大的开销,影响程序性能。
创建线程池
- ExecutorService 是 Java 提供的线程池接口。
通过ThreadPoolExecutor类创建线程池
- 使用指定的参数创建线程池对象:
- 参数说明:
- corePoolSize:核心线程数,线程池中始终保持的线程数量。
- maximumPoolSize:最大线程数,线程池中允许的最大线程数量。
- keepAliveTime:临时线程的存活时间,当线程空闲时间超过该值时,临时线程会被终止。
- unit:keepAliveTime 的时间单位,如秒、毫秒等。
- workQueue:任务队列,用于存放等待执行的任务。
- threadFactory:线程工厂,用于创建新线程。
- handler:拒绝策略,当线程池和任务队列都满时,如何处理新任务。
- 参数说明:
- 任务拒绝策略
| 策略 | 说明 |
|---|---|
| TreadPoolExecutor.AbortPolicy | 丢弃任务并抛出 RejectedExecutionException 异常,默认策略。 |
| TreadPoolExecutor.CallerRunsPolicy | 由主线程执行该任务。 |
| TreadPoolExecutor.DiscardPolicy | 丢弃该任务,不抛出异常。 |
| TreadPoolExecutor.DiscardOldestPolicy | 丢弃任务队列中最旧的任务,然后尝试提交当前任务。 |
public class MyClass {
public static void main(String[] args) {
// 1. 使用ThreadPoolExecutor类创建线程池
ExecutorService threadPool = new ThreadPoolExecutor(
5, // corePoolSize
10, // maximumPoolSize
60, // keepAliveTime
TimeUnit.SECONDS, // unit
new ArrayBlockingQueue<>(100) // workQueue
Executors.defaultThreadFactory(), // threadFactory
new ThreadPoolExecutor.AbortPolicy() // handler
);
}
}补充说明
- 什么时候会创建临时线程?
- 当任务数量超过核心线程数,且任务队列已满时,线程池会创建临时线程来处理任务,直到达到最大线程数。
- 什么时候会拒绝任务?
- 当线程池中的线程数(包括核心线程和临时线程)达到最大线程数,且任务队列也已满时,新的任务会被拒绝,根据指定的拒绝策略进行处理。
处理Runnable任务
- ExecutorService 常用方法:
| 方法 | 说明 |
|---|---|
| void execute(Runnable command) | 执行Runnable任务 |
| <T> Future<T> submit(Callable<T> task) | 执行Callable任务,并返回Future对象 |
| void shutdown() | 等待全部任务执行完毕,然后关闭线程池 |
| List<Runnable> shutdownNow() | 立即关闭线程池,停止正在执行的任务,返回未执行的任务列表 |
使用线程池处理 Runnable 任务的示例:
- 这里假设已经按照实现Runnable接口部分创建了一个
MyRunnable类。
public class Main {
public static void main(String[] args) {
// 创建线程池
ExecutorService threadPool = Executors.newFixedThreadPool(5);
// 提交多个Runnable任务到线程池
Runnable task = new MyRunnable();
pool.execute(task);
pool.execute(task);
pool.execute(task);
// 关闭线程池
threadPool.shutdown();
}
}注意
在生产环境中,一般不会关闭线程池,因为线程池的目的是为了复用线程,提高性能。 关闭线程池会导致线程资源被释放,无法再复用。