推荐答案
在 Java 中,可以通过 java.util.concurrent.ThreadPoolExecutor 类来创建自定义线程池。以下是一个示例代码:
// www.javascriptcn.com code example
import java.util.concurrent.*;
public class CustomThreadPoolExample {
public static void main(String[] args) {
// 创建自定义线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, // 核心线程数
4, // 最大线程数
60, // 空闲线程存活时间
TimeUnit.SECONDS, // 时间单位
new LinkedBlockingQueue<>(10), // 任务队列
Executors.defaultThreadFactory(), // 线程工厂
new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
);
// 提交任务
for (int i = 0; i < 10; i++) {
executor.execute(() -> {
System.out.println("Task executed by " + Thread.currentThread().getName());
});
}
// 关闭线程池
executor.shutdown();
}
}本题详细解读
1. 线程池的核心参数
在创建自定义线程池时,ThreadPoolExecutor 构造函数需要以下几个核心参数:
- corePoolSize: 核心线程数,线程池中始终保持存活的线程数量。
- maximumPoolSize: 最大线程数,线程池中允许的最大线程数量。
- keepAliveTime: 空闲线程存活时间,当线程池中的线程数量超过核心线程数时,多余的空闲线程在终止前等待新任务的最长时间。
- unit: 时间单位,通常为
TimeUnit.SECONDS或TimeUnit.MILLISECONDS。 - workQueue: 任务队列,用于存放待执行的任务。常见的队列类型有
LinkedBlockingQueue和ArrayBlockingQueue。 - threadFactory: 线程工厂,用于创建新线程。可以使用
Executors.defaultThreadFactory()来使用默认的线程工厂。 - handler: 拒绝策略,当任务队列已满且线程池中的线程数量达到最大线程数时,如何处理新提交的任务。常见的拒绝策略有
AbortPolicy、CallerRunsPolicy、DiscardPolicy和DiscardOldestPolicy。
2. 线程池的工作流程
- 当提交一个新任务时,线程池首先会检查当前线程数是否小于核心线程数。如果是,则创建一个新线程来执行任务。
- 如果当前线程数已达到核心线程数,线程池会将任务放入任务队列中等待执行。
- 如果任务队列已满,线程池会检查当前线程数是否小于最大线程数。如果是,则创建一个新线程来执行任务。
- 如果当前线程数已达到最大线程数且任务队列已满,线程池会根据指定的拒绝策略来处理新提交的任务。
3. 线程池的关闭
- shutdown(): 平滑地关闭线程池,不再接受新任务,但会等待已提交的任务执行完毕。
- shutdownNow(): 立即关闭线程池,尝试中断正在执行的任务,并返回未执行的任务列表。
通过合理配置这些参数,可以创建适合特定应用场景的自定义线程池。