【高并发系列】面试官:你能手写一个线程池吗?ThreadPoolExecutor源码剖析 + 实现(建议收藏)

手写Java线程池及与JDK线程池对比

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

📚博主匠心之作,强推专栏

沉淀

一、为什么要自己实现线程池?

很多同学可能会问:为什么要自己实现线程池?直接用JDK的不就行了?

确实,在实际开发中我们都是直接使用JDK提供的ThreadPoolExecutor。但是,自己动手实现一个线程池有这些好处:

  1. 深入理解原理

    • 线程池的核心运作机制
    • 任务调度策略
    • 线程生命周期管理
  2. 掌握设计思想

    • 池化技术的精髓
    • 生产者-消费者模型
    • 任务队列的设计
  3. 面试加分项

    • 能够清晰地讲解线程池原理
    • 展示动手能力
    • 体现技术深度

二、实现目标

我们将实现一个简化版的ThreadPoolExecutor,包含以下核心功能:

  1. 线程池基本参数

    • 核心线程数
    • 最大线程数
    • 任务队列
    • 拒绝策略
  2. 任务提交与执行

    • 任务提交接口
    • 任务执行机制
    • 线程复用
  3. 线程管理

    • 线程创建
    • 线程回收
    • 状态管理
  4. 拒绝策略

    • 直接拒绝
    • 调用者执行
    • 丢弃任务
    • 丢弃最老任务

三、分步实现

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()) {
   
   
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值