线程池基础面试题

问题 1:什么是 Java 线程池?它的核心设计思想是什么?

Java 线程池(ThreadPoolExecutor)是 JUC(java.util.concurrent)包下的线程管理工具,本质是一组预先创建的线程集合 + 任务队列 + 管理策略。

核心设计思想:

  • 避免频繁创建 / 销毁线程的性能开销(线程的创建需要占用系统资源、销毁需要回收资源);
  • 统一管理线程的生命周期,控制并发线程数量,防止因创建过多线程导致 CPU / 内存耗尽;
  • 实现任务的异步执行和复用线程。

注意: 在我们的实际开发过程中也是使用线程池的方式来进行管理,这样做的好处是对线程的有效调度,以及避免了过多的创建和销毁。

问题 2:线程池的核心作用有哪些?

1.降低资源消耗:复用已创建的线程,减少线程创建 / 销毁的系统开销;
2.提高响应速度:任务到达时无需等待线程创建,直接使用空闲线程执行;
3.便于线程管理:可控制最大并发数、设置线程存活时间、监控线程状态等;
4.增强可扩展性:支持任务拒绝策略、线程工厂自定义、任务执行前后钩子等扩展功能。

问题 3:Java 中创建线程池有哪两种核心方式?分别说明适用场景

方式 1:通过ThreadPoolExecutor直接创建(推荐,可精准控制参数);
方式 2:通过Executors工具类创建(简单,但易引发资源问题,阿里开发手册不推荐)。

代码示例1:ThreadPoolExecutor 直接创建(推荐)

package main.threadpool;

import java.util.concurrent.*;

public class ThreadPoolDemo {
    public static void main(String[] args) {
        // 1. 定义线程池核心参数
        int corePoolSize = 4; // 核心线程数(常驻线程数)
        int maximumPoolSize = 10; // 最大线程数
        long keepAliveTime = 10; // 非核心线程空闲存活时间
        TimeUnit unit = TimeUnit.SECONDS; // 存活时间单位
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(5); // 任务队列(容量3)
        ThreadFactory threadFactory = Executors.defaultThreadFactory(); // 线程工厂(创建线程)
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy(); // 拒绝策略

        // 2. 创建线程池
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );

        // 3. 提交任务
        for (int i = 1; i <= 10; i++) {
            int taskNum = i;
            threadPool.execute(() -> {
                System.out.println("线程" + Thread.currentThread().getName() + "执行任务" + taskNum);
                try {
                    Thread.sleep(1000); // 模拟任务执行耗时
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        // 4. 关闭线程池(用完必须关闭,否则进程不会结束)
        threadPool.shutdown();
    }
}

参数说明:

  • corePoolSize:核心线程数,即使空闲也不会销毁(除非设置allowCoreThreadTimeOut(true));
  • maximumPoolSize:线程池能创建的最大线程数;
  • keepAliveTime:非核心线程空闲超过该时间会被销毁;
  • workQueue:任务队列,核心线程满时,新任务会放入队列;
  • threadFactory:自定义线程创建方式(如设置线程名、优先级);
    handler:拒绝策略(队列满 + 最大线程数满时,处理新任务的方式)。
package main.threadpool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

public class ExecutorsDemo {
    public static void main(String[] args) {
        // 1. 创建常见的线程池(Executors提供的快捷方式)
        // 方式1:固定线程数线程池
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
        // 方式2:单线程线程池
        ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
        // 方式3:缓存线程池(按需创建,空闲60s销毁)
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        // 方式4:定时任务线程池
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);

        // 2. 使用固定线程池执行任务
        for (int i = 1; i <= 5; i++) {
            int taskNum = i;
            fixedThreadPool.execute(() -> {
                System.out.println("线程" + Thread.currentThread().getName() + "执行任务" + taskNum);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        // 3. 关闭线程池
        fixedThreadPool.shutdown();
    }
}

Executors 的问题

  • newFixedThreadPool/newSingleThreadExecutor:队列使用LinkedBlockingQueue(无界队列),任务过多会导致 OOM;
  • newCachedThreadPool:最大线程数为Integer.MAX_VALUE,可能创建大量线程导致 OOM;
  • 因此阿里开发手册要求:禁止使用 Executors 创建线程池,必须手动通过 ThreadPoolExecutor 创建。

问题 3:线程池的执行流程是什么?

1.任务提交时,先判断核心线程池是否已满:未满则创建核心线程执行任务;
2.核心线程池已满,判断任务队列是否已满:未满则将任务放入队列;
3.任务队列已满,判断线程池是否达到最大线程数:未达到则创建非核心线程执行任务;
4.达到最大线程数,则触发拒绝策略处理任务。

问题 4:线程池的 4 种拒绝策略分别是什么

1.AbortPolicy(默认):直接抛出RejectedExecutionException异常,终止任务;
2.CallerRunsPolicy:由提交任务的线程(如 main 线程)自己执行任务;
3.DiscardPolicy:直接丢弃新任务,无任何提示;
4.DiscardOldestPolicy:丢弃队列中最旧的任务,将新任务加入队列。

posted @ 2026-03-10 21:27  白鹿为溪  阅读(71)  评论(0)    收藏  举报