Files
interview/questions/thread-pool-params.md
yasinshaw fe2e6dc2f2 feat: add 50 backend interview questions and answers
Generated comprehensive interview preparation materials covering:
- Distributed systems (transactions, locks, ID generation, consistency)
- Database (indexing, sharding, replication, transactions)
- Caching (Redis, cache problems, distributed lock)
- Message queues (RocketMQ, Kafka)
- Concurrency (ThreadLocal, ConcurrentHashMap, thread pools)
- JVM (GC, memory, tuning)
- System design (seckill, short URL, IM, feed, LBS)
- Algorithms (B+ tree, LRU, Red-Black tree, Skip list, Timing wheel)
- Network (TCP/IP, HTTP/HTTPS)
- Security (encryption, SQL injection, XSS)
- Performance tuning
- Design patterns
- Microservices (Spring Boot, Gateway, Service Mesh)
- Container orchestration (Kubernetes, Docker)
- CI/CD, observability

Each file includes:
- Detailed questions
- Comprehensive answers
- Code examples
- Real project experience
- Alibaba P7 level requirements

Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-03-01 00:09:50 +08:00

14 KiB
Raw Blame History

线程池核心参数详解

问题

  1. 线程池的核心参数有哪些?各自的作用是什么?
  2. 如何合理设置线程池大小?
  3. 线程池的拒绝策略有哪些?如何自定义?
  4. 线程池如何优雅关闭?
  5. 线程池的监控指标有哪些?
  6. 在实际项目中如何使用线程池?

标准答案

1. 线程池核心参数

ThreadPoolExecutor 构造函数

public ThreadPoolExecutor(
    int corePoolSize,              // 核心线程数
    int maximumPoolSize,           // 最大线程数
    long keepAliveTime,            // 非核心线程空闲存活时间
    TimeUnit unit,                 // 时间单位
    BlockingQueue<Runnable> workQueue,  // 任务队列
    ThreadFactory threadFactory,        // 线程工厂
    RejectedExecutionHandler handler    // 拒绝策略
)

参数详解

1. corePoolSize核心线程数

  • 说明:即使空闲也保留的线程数
  • 默认值:创建时无核心线程(任务到达时才创建)
  • 预热prestartAllCoreThreads() 提前创建核心线程
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    10,  // 核心线程数
    20,  // 最大线程数
    ...
);

// 预热核心线程
executor.prestartAllCoreThreads();

2. maximumPoolSize最大线程数

  • 说明:线程池允许的最大线程数
  • 限制maximumPoolSize >= corePoolSize
  • 动态调整:运行时可通过 setMaximumPoolSize() 调整
// 动态调整最大线程数
executor.setMaximumPoolSize(50);

3. keepAliveTime非核心线程存活时间

  • 说明:非核心线程的空闲存活时间
  • 超时回收:超过时间后,线程会被回收
  • 允许回收核心线程allowCoreThreadTimeOut(true)
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    10,
    20,
    60,  // 存活时间
    TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(100)
);

// 允许核心线程超时回收
executor.allowCoreThreadTimeOut(true);

4. workQueue任务队列

常见队列

队列 特性 适用场景
SynchronousQueue 不存储,直接传递 高并发、低延迟
LinkedBlockingQueue 无界队列(默认 Integer.MAX_VALUE 任务提交频繁
ArrayBlockingQueue 有界队列 防止资源耗尽
PriorityBlockingQueue 优先级队列 优先级任务

示例

// 1. SynchronousQueue高并发
ExecutorService executor1 = new ThreadPoolExecutor(
    10, 20,
    60L, TimeUnit.SECONDS,
    new SynchronousQueue<Runnable>()  // 无队列,直接传递
);

// 2. LinkedBlockingQueue无界
ExecutorService executor2 = new ThreadPoolExecutor(
    10, 20,
    60L, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(1000)  // 队列长度 1000
);

// 3. PriorityBlockingQueue优先级
ExecutorService executor3 = new ThreadPoolExecutor(
    10, 20,
    60L, TimeUnit.SECONDS,
    new PriorityBlockingQueue<>(100)
);

5. threadFactory线程工厂

作用

  • 设置线程名称(便于排查)
  • 设置线程优先级
  • 设置是否为守护线程

示例

ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
    .setNameFormat("order-pool-%d")  // 线程名称前缀
    .setDaemon(false)               // 非守护线程
    .setPriority(Thread.NORM_PRIORITY)
    .build();

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    10, 20,
    60L, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(100),
    namedThreadFactory
);

6. handler拒绝策略

内置策略

策略 说明
AbortPolicy默认 抛出异常
CallerRunsPolicy 调用者线程执行
DiscardPolicy 静默丢弃
DiscardOldestPolicy 丢弃最旧的任务
// 自定义拒绝策略
RejectedExecutionHandler handler = new RejectedExecutionHandler() {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        // 记录日志
        log.warn("任务被拒绝: {}", r);

        // 重试(加入队列等待)
        if (!executor.isShutdown()) {
            try {
                executor.getQueue().put(r);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
};

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    10, 20,
    60L, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(100),
    handler
);

2. 线程池工作流程

任务提交
    ↓
核心线程数 < corePoolSize
├─ 是 → 创建核心线程并执行
└─ 否 → 继续
    ↓
队列未满?
├─ 是 → 加入队列
└─ 否 → 继续
    ↓
线程数 < maximumPoolSize
├─ 是 → 创建非核心线程并执行
└─ 否 → 继续
    ↓
拒绝策略

3. 合理设置线程池大小

CPU 密集型任务

特点:主要消耗 CPU 资源(计算、加密)

公式

线程数 = CPU 核心数 + 1

原因

  • CPU 密集型任务不需要太多线程
  • +1 是为了当某线程因页故障等原因暂停时CPU 不会闲置

示例

int cpuCore = Runtime.getRuntime().availableProcessors();  // 8
int poolSize = cpuCore + 1;  // 9

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    poolSize,  // 核心线程数
    poolSize,  // 最大线程数
    0L, TimeUnit.MILLISECONDS,
    new LinkedBlockingQueue<>(100)
);

IO 密集型任务

特点:主要等待 IO网络、磁盘

公式

线程数 = CPU 核心数 × (1 + IO 耗时 / CPU 耗时)

示例

// IO 耗时 / CPU 耗时 = 2IO 占 2/3CPU 占 1/3
int cpuCore = Runtime.getRuntime().availableProcessors();  // 8
int poolSize = cpuCore * (1 + 2);  // 24

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    cpuCore,  // 核心线程数 = CPU 核心数
    poolSize, // 最大线程数
    60L, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(500)
);

通用公式

线程数 = CPU 核心数 × 目标 CPU 使用率 × (1 + IO 耗时 / CPU 耗时)

参数调整

  • 目标 CPU 使用率80% - 90%
  • IO / CPU 比例:通过压测获得

4. 线程池监控

监控指标

指标 说明 获取方法
活跃线程数 正在执行任务的线程数 getActiveCount()
已完成任务数 历史完成的任务总数 getCompletedTaskCount()
总任务数 已完成 + 正在执行 getTaskCount()
队列大小 队列中待执行任务数 getQueue().size()
最大线程数 历史最大线程数 getLargestPoolSize()
线程池是否关闭 isShutdown() isShutdown()

监控代码

@Component
public class ThreadPoolMonitor {

    @Autowired
    private Map<String, ThreadPoolExecutor> executorMap;

    @Scheduled(fixedRate = 60000)  // 每分钟
    public void monitor() {
        executorMap.forEach((name, executor) -> {
            ThreadPoolExecutorStats stats = new ThreadPoolExecutorStats();
            stats.setName(name);
            stats.setCorePoolSize(executor.getCorePoolSize());
            stats.setMaximumPoolSize(executor.getMaximumPoolSize());
            stats.setActiveCount(executor.getActiveCount());
            stats.setCompletedTaskCount(executor.getCompletedTaskCount());
            stats.setTaskCount(executor.getTaskCount());
            stats.setQueueSize(executor.getQueue().size());
            stats.setLargestPoolSize(executor.getLargestPoolSize());

            // 上报到监控系统Prometheus、Grafana
            Metrics.report(stats);

            // 告警判断
            if (executor.getActiveCount() >= executor.getMaximumPoolSize() * 0.8) {
                alert("线程池 " + name + " 负载过高");
            }
        });
    }
}

Actuator 监控Spring Boot

依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

配置

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics
  metrics:
    export:
      prometheus:
        enabled: true

访问

curl http://localhost:8080/actuator/metrics
curl http://localhost:8080/actuator/metrics/executor.pool.size

5. 线程池优雅关闭

问题

不优雅关闭的后果:

  • 已提交的任务可能丢失
  • 正在执行的任务可能被中断

shutdown()

executor.shutdown();

try {
    // 等待任务完成
    if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
        // 超时,强制关闭
        executor.shutdownNow();
    }
} catch (InterruptedException e) {
    executor.shutdownNow();
    Thread.currentThread().interrupt();
}

特点

  • 不再接受新任务
  • 等待已提交的任务完成
  • 超时后可调用 shutdownNow() 强制关闭

shutdownNow()

List<Runnable> unfinishedTasks = executor.shutdownNow();

特点

  • 不再接受新任务
  • 尝试停止正在执行的任务(通过 Thread.interrupt()
  • 返回未执行的任务列表

6. Spring 线程池配置

配置类

@Configuration
public class ThreadPoolConfig {

    @Bean("orderThreadPool")
    public ThreadPoolExecutor orderThreadPool() {
        return new ThreadPoolExecutor(
            10,  // 核心线程数
            20,  // 最大线程数
            60L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(100),
            new ThreadFactoryBuilder()
                .setNameFormat("order-pool-%d")
                .build(),
            new ThreadPoolExecutor.CallerRunsPolicy()
        );
    }

    @Bean("emailThreadPool")
    public ThreadPoolExecutor emailThreadPool() {
        return new ThreadPoolExecutor(
            5,
            10,
            60L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(50),
            new ThreadFactoryBuilder()
                .setNameFormat("email-pool-%d")
                .build(),
            new ThreadPoolExecutor.CallerRunsPolicy()
        );
    }
}

使用

@Service
public class OrderService {

    @Autowired
    @Qualifier("orderThreadPool")
    private ThreadPoolExecutor orderThreadPool;

    public void createOrder(Order order) {
        // 异步处理
        orderThreadPool.execute(() -> {
            // 处理订单
            processOrder(order);
        });
    }
}

@AsyncSpring 异步)

配置

@Configuration
@EnableAsync
public class AsyncConfig {

    @Bean("asyncExecutor")
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(20);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("async-pool-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

使用

@Service
public class EmailService {

    @Async("asyncExecutor")
    public void sendEmail(String to, String subject, String body) {
        // 异步发送邮件
        mailSender.send(to, subject, body);
    }
}

7. 实际项目经验

案例 1线程池参数调优

问题

  • 订单接口响应慢
  • CPU 使用率低30%),线程池队列满

分析

// 原配置
corePoolSize = 5
maximumPoolSize = 10
queue = LinkedBlockingQueue(100)

问题

  • 线程数太少,任务堆积在队列
  • 数据库连接池用满,等待连接

优化

// 优化后配置
corePoolSize = 20      // 增加
maximumPoolSize = 50    // 增加
queue = LinkedBlockingQueue(500)  // 增加

结果:响应时间从 2s 降至 200ms


案例 2动态线程池

需求:根据流量动态调整线程池大小

实现

@Component
public class DynamicThreadPoolManager {

    private final Map<String, ThreadPoolExecutor> executorMap = new ConcurrentHashMap<>();

    @PostConstruct
    public void init() {
        // 定时调整线程池大小
        ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(this::adjustThreadPoolSize, 1, 1, TimeUnit.MINUTES);
    }

    private void adjustThreadPoolSize() {
        executorMap.forEach((name, executor) -> {
            // 获取当前负载
            int activeCount = executor.getActiveCount();
            int maximumPoolSize = executor.getMaximumPoolSize();

            // 负载 > 80%,扩容
            if (activeCount > maximumPoolSize * 0.8) {
                int newSize = Math.min(maximumPoolSize * 2, 100);
                executor.setMaximumPoolSize(newSize);
                log.info("扩容线程池: {} -> {}", name, newSize);
            }
            // 负载 < 20%,缩容
            else if (activeCount < maximumPoolSize * 0.2) {
                int newSize = Math.max(maximumPoolSize / 2, executor.getCorePoolSize());
                executor.setMaximumPoolSize(newSize);
                log.info("缩容线程池: {} -> {}", name, newSize);
            }
        });
    }
}

8. 阿里 P7 加分项

深度理解

  • 理解线程池的状态转换RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED
  • 理解 Worker 的实现原理(继承 AQS、实现 Runnable
  • 理解线程池的异常处理机制

实战经验

  • 有线程池参数调优的经验
  • 有处理线程池饱和问题的经验
  • 有线程池监控和告警的经验

架构能力

  • 能设计动态线程池(根据流量调整)
  • 能设计线程池隔离(不同业务独立线程池)
  • 能设计线程池监控体系

技术选型

  • 了解 ForkJoinPool(工作窃取线程池)
  • 了解 ScheduledThreadPoolExecutor(定时任务线程池)
  • 了解 Vert.x、WebFlux 等响应式框架的线程模型