Java线程池高频面试题(含实战代码与源码解析)

Java线程池高频面试题(含实战代码与源码解析)

一、线程池核心参数(必考)

核心参数定义

线程池的核心逻辑封装在 ThreadPoolExecutor 中,其构造函数的7个参数决定了线程池的行为特性:

public ThreadPoolExecutor(
    int corePoolSize,        // 核心线程数(常驻线程,空闲时不销毁)
    int maximumPoolSize,     // 最大线程数(核心+非核心线程的峰值)
    long keepAliveTime,      // 非核心线程空闲存活时间
    TimeUnit unit,           // 存活时间单位(如秒、毫秒)
    BlockingQueue<Runnable> workQueue, // 任务队列(缓存待执行任务)
    ThreadFactory threadFactory,       // 线程工厂(定制线程名称、优先级等)
    RejectedExecutionHandler handler   // 拒绝策略(任务满时的处理方式)
)

关键参数深度解析

1. 核心线程数 vs 最大线程数
  • corePoolSize:线程池的“基础兵力”,即使空闲也会保留(除非设置 allowCoreThreadTimeOut=true)。
  • maximumPoolSize:线程池的“峰值兵力”,仅当队列满时才会创建非核心线程,任务完成后非核心线程会在 keepAliveTime 后销毁。

示例场景corePoolSize=2maximumPoolSize=5workQueue=容量10

  • 提交2个任务:核心线程直接执行;
  • 提交第3~12个任务:进入队列等待;
  • 提交第13个任务:创建第3个非核心线程;
  • 提交第16个任务:线程数达5,触发拒绝策略。
2. 任务队列类型(性能与安全关键)
队列类型 特点 适用场景 风险点
ArrayBlockingQueue 有界队列,需指定容量 核心业务,控制任务积压上限 容量过小易触发拒绝策略
LinkedBlockingQueue 无界队列(默认Integer.MAX_VALUE 非核心任务,允许临时积压 任务过多导致内存溢出(OOM)
SynchronousQueue 不存储任务,直接提交给线程 任务执行快,需即时响应 线程数不足时立即触发拒绝策略
3. 线程工厂与拒绝策略
  • 线程工厂:默认使用 Executors.defaultThreadFactory(),建议自定义以规范线程名称(如 task-pool-1-thread-1),便于问题排查。
  • 拒绝策略:详见第三章。

二、线程池工作流程(核心执行逻辑)

四步执行规则

线程池处理任务的流程严格遵循以下顺序(源码对应 ThreadPoolExecutor#execute 方法):

  1. 核心线程未满:创建核心线程执行任务;
  2. 核心线程已满:任务放入工作队列等待;
  3. 队列已满:创建非核心线程执行任务;
  4. 线程数达最大值:触发拒绝策略。

源码核心逻辑片段

public void execute(Runnable command) {
   
   
    if (command == null) throw new NullPointerException();
    int c = ctl.get();
    // 1. 核心线程未满,创建核心线程
    if (workerCountOf(c) < corePoolSize) {
   
   
        if (addWorker(command, true)) return;
        c = ctl.get();
    }
    // 2. 核心线程满,尝试入队
    if (isRunning(c) && workQueue.offer(command)) {
   
   
        int recheck = ctl.get();
        if (!isRunning(recheck) && remove(command))
            reject(command);
        else if (workerCountOf(recheck) == 0)
            addWorker(null, false);
    }
    // 3. 队列满,尝试创建非核心线程
    else if (!addWorker(command, false))
        // 4. 线程数达最大值,触发拒绝策略
        reject(command);
}

代码案例:模拟工作流程

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolFlowDemo {
   
   
    public static void main(String[] args) {
   
   
        // 配置:核心2,最大5,队列容量3,拒绝策略为CallerRunsPolicy
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            2, 5, 60, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(3),
            r -> new Thread(r, "demo-pool-thread-"), // 自定义线程工厂
            new ThreadPoolExecutor.CallerRunsPolicy()
        );

        // 提交6个任务(核心2 + 队列3 = 5,第6个触发扩容非核心线程)
        for (int i = 1; i <= 6; i++) {
   
   
            int taskId = i;
            executor.execute(() -> {
   
   
                System.out.printf("线程[%s]执行任务%d%n", 
                                 Thread.currentThread().getName(), taskId);
                try {
   
    Thread.sleep(100); } catch (InterruptedException e) {
   
   }
            });
            System.out.printf("提交任务%d后,线程数:%d,队列大小:%d%n",
                             taskId, executor.getPoolSize(), executor.getQueue
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值