🔥 本文将带你手写一个Java线程池,从最基础的功能开始,逐步实现ThreadPoolExecutor的核心特性。通过这个过程,你将深入理解线程池的工作原理和设计思想。
📚博主匠心之作,强推专栏:

文章目录
一、为什么要自己实现线程池?
很多同学可能会问:为什么要自己实现线程池?直接用JDK的不就行了?
确实,在实际开发中我们都是直接使用JDK提供的ThreadPoolExecutor。但是,自己动手实现一个线程池有这些好处:
-
深入理解原理:
- 线程池的核心运作机制
- 任务调度策略
- 线程生命周期管理
-
掌握设计思想:
- 池化技术的精髓
- 生产者-消费者模型
- 任务队列的设计
-
面试加分项:
- 能够清晰地讲解线程池原理
- 展示动手能力
- 体现技术深度
二、实现目标
我们将实现一个简化版的ThreadPoolExecutor,包含以下核心功能:
-
线程池基本参数:
- 核心线程数
- 最大线程数
- 任务队列
- 拒绝策略
-
任务提交与执行:
- 任务提交接口
- 任务执行机制
- 线程复用
-
线程管理:
- 线程创建
- 线程回收
- 状态管理
-
拒绝策略:
- 直接拒绝
- 调用者执行
- 丢弃任务
- 丢弃最老任务
三、分步实现
1. 基础框架搭建
首先搭建最基本的框架,包括:
- 线程池接口定义
- 核心参数
- 基础任务提交功能
四、具体实现
让我们一步步实现这个线程池。整个实现过程会分为几个关键部分:接口定义、状态管理、拒绝策略和核心实现。
4.1 基础接口定义
首先,我们需要定义线程池的基础接口。一个好的接口设计应该清晰地表达线程池的核心功能。我们这里定义了以下几个核心方法:
execute: 提交任务到线程池shutdown: 优雅关闭线程池- 以及几个状态查询方法
这些方法构成了线程池对外的基本功能:
/**
* 自定义线程池接口
*/
public interface ThreadPool {
// 提交任务
void execute(Runnable task);
// 关闭线程池
void shutdown();
// 获取线程池状态
int getPoolStatus();
// 获取活跃线程数
int getActiveCount();
// 获取已完成任务数
long getCompletedTaskCount();
}
4.2 线程池状态定义
线程池的状态管理是一个关键部分。线程池在运行过程中会经历不同的状态:
- RUNNING: 正常运行,可以接收新任务
- SHUTDOWN: 不再接收新任务,但会处理队列中的任务
- STOPPED: 完全停止,不再处理任何任务
这些状态之间的转换需要严格控制:
public class ThreadPoolStatus {
// 运行中
public static final int RUNNING = 0;
// 关闭中
public static final int SHUTDOWN = 1;
// 已停止
public static final int STOPPED = 2;
// 状态变更方法
public static boolean isRunning(int state) {
return state == RUNNING;
}
public static boolean isShutdown(int state) {
return state >= SHUTDOWN;
}
}
4.3 拒绝策略定义
当线程池无法处理新任务时(比如队列满了,或者线程池已关闭),就需要拒绝策略来处理这些任务。我们实现了两种常见的拒绝策略:
- AbortPolicy: 直接抛出异常,这是最简单直接的方式
- CallerRunsPolicy: 在调用者线程中执行任务,这可以起到限流作用
/**
* 拒绝策略接口
*/
public interface RejectedExecutionHandler {
void rejectedExecution(Runnable task, CustomThreadPoolExecutor executor);
}
/**
* 直接抛出异常
*/
public class AbortPolicy implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable task, CustomThreadPoolExecutor executor) {
throw new RejectedExecutionException("Task " + task.toString() +
" rejected from " + executor.toString());
}
}
/**
* 由调用者线程执行
*/
public class CallerRunsPolicy implements RejectedExecutionHandler {
@Override
public void rejectedExecution(Runnable task, CustomThreadPoolExecutor executor) {
if (!executor.isShutdown()) {
手写Java线程池及与JDK线程池对比

最低0.47元/天 解锁文章
672

被折叠的 条评论
为什么被折叠?



