阅读本文前,建议先阅读《Java 线程与原理》了解 Java 线程的基本使用(Thread、Runnable、Callable 和 FutureTask的关系)
Executor 框架
Executor 框架是 Java 5 引入的并发工具,位于 java.util.concurrent 包中,其核心目标是将线程任务的提交与任务的执行解耦,是 Java 线程池的核心实现框架。

Executor 框架的核心接口:
- Executor :最顶层的接口,定义了
execute(Runnable command)方法。
csharp
public interface Executor {
void execute(Runnable command);
}
- ExecutorService :扩展了
Executor,增加了管理线程池生命周期的方法(如shutdown()、submit()、invokeAll()等)。
java
public interface ExecutorService extends Executor {
<T> Future<T> submit(Callable<T> task);
List<Runnable> shutdownNow();
boolean awaitTermination(long timeout, TimeUnit unit);
// ...
}
- ScheduledExecutorService:支持延迟或周期性执行任务。
arduino
public interface ScheduledExecutorService extends ExecutorService {
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);
// ...
}
- ThreadPoolExecutor:ExecutorService 的核心实现类,提供了丰富的线程池配置选项。
接口与类关系:


Executor 框架的使用示意图:

ThreadPoolExecutor
构造函数:
java
public ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler
)
参数说明:
| 参数 | 说明 |
|---|---|
corePoolSize |
核心线程数。即使空闲,这些线程也不会被回收(除非设置 allowCoreThreadTimeOut(true))。当低于这个数值,总是新建线程执行任务;超过这个数值后,会把任务放到 workQueue排队,当队列满时,才在 maximumPoolSize 范围内新建线程执行任务。 |
maximumPoolSize |
最大线程数。当活动线程数达到这个数值后,将会被拒绝掉(见后面的 RejectedExecutionHandler )。 |
keepAliveTime |
非核心线程闲置时的超时时长。超过这个时长,闲置的非核心线程就会被回收。 |
unit |
keepAliveTime 参数的时间单位,有 TimeUnit.MILLISECOND 、TimeUnit.SECOND 、TimeUnit.MINUTE 等 |
workQueue |
任务队列,用于缓存待执行的任务。常用实现:1、ArrayBlockingQueue:基于数组结构的的先进先出有界阻塞队列,此队列创建时必须指定大小。2、LinkedBlockingQueue:基于链表结构的先进先出无界阻塞队列,如果创建时没有指定此队列大小,则默认为 Integer.MAX_VALUE 。3、SynchronousQueue:一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态。相当于队列容量大小为 1 。4、PriorityBlockingQueue:一个具有优先级的无限阻塞队列,可用于设置任务处理的优先级。 |
threadFactory |
线程工厂,用于自定义线程创建(如命名、优先级等)。 |
handler |
拒绝策略,当线程池和队列都满时如何处理新任务。常用实现:1、AbortPolicy(默认):丢弃任务,并抛出 RejectedExecutionException 异常。2、DiscardPolicy:也是丢弃任务,但是不抛出异常。3、DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)4、CallerRunsPolicy:由调用线程处理该任务 |
ThreadPoolExecutor 线程池处理流程:


ThreadPoolExecutor 线程池使用示例:
java
import java.util.concurrent.*;
public class ThreadPoolExample {
public static void main(String[] args) {
ThreadFactory namedThreadFactory = r -> {
Thread t = new Thread(r, "MyPool-Thread");
t.setDaemon(false);
return t;
};
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(100);
RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2,
4,
30,
TimeUnit.SECONDS,
workQueue,
namedThreadFactory,
handler
);
for (int i = 0; i < 10; i++) {
final int taskId = i;
executor.submit(() -> {
System.out.println("Task " + taskId + " executed by " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
executor.shutdown();
}
}
Executors 工厂类
Java 提供了 Executors 工具类,用于快速创建常见线程池:
| 方法 | 说明 | 内部实现 |
|---|---|---|
newFixedThreadPool(int n) |
固定大小线程池 | core = max = n,无界队列![]() |
newCachedThreadPool() |
缓存线程池 | core = 0,max = Integer.MAX_VALUE,SynchronousQueue![]() ![]() |
newSingleThreadExecutor() |
单线程池 | core = max = 1,无界队列![]() |
newScheduledThreadPool(int n) |
支持定时/周期任务 | ScheduledThreadPoolExecutor |
其中,newFixedThreadPool 和 newCachedThreadPool 在高负载下可能导致 OOM(因使用无界队列或过多线程)。因此,生产环境强烈建议手动创建 ThreadPoolExecutor 并明确参数。
ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor 是专门用于延迟执行或周期性执行任务。它是 ThreadPoolExecutor 的子类,同时实现了 ScheduledExecutorService 接口。
ScheduledThreadPoolExecutor 特性:
- 支持一次性延迟执行。
- 支持 固定频率(fixed-rate)或 固定延迟(fixed-delay)的周期性任务。
- 线程复用:多个定时任务共享线程池中的线程,避免频繁创建/销毁线程。
- 线程池等待队列默认使用
DelayedWorkQueue(一种无界优先队列),大量任务堆积可能导致 OOM。 - 比 Timer / TimerTask 更安全、更灵活(Timer 是单线程,异常会导致整个调度器崩溃)。若某个任务抛出未捕获异常,该任务将终止,但不会影响其他任务。
- 可通过 ScheduledFuture.cancel() 取消任务。
- 调用 shutdown() 关闭线程池后,已提交的任务仍会执行;shutdownNow() 尝试中断正在执行的任务。

线程池最佳实践
- 避免使用 Executors 创建普通线程池 ,应显式使用
ThreadPoolExecutor。 - 合理设置 corePoolSize 和 maximumPoolSize,根据 CPU 核心数和任务类型(CPU 密集型 vs IO 密集型)调整。
- 使用有界队列,防止内存溢出。
- 自定义 ThreadFactory,为线程命名便于排查问题。
- 合理处理异常 :在
Runnable或Callable中捕获异常,避免线程静默退出。 - 优雅关闭线程池:
java
executor.shutdown();
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
参考
- 《Java并发编程的艺术》
【本文首发于:JavaArchJourney】



