Java 中的线程池是如何实现 ?
参考答案:
Java 中的线程池是通过 java.util.concurrent
包中的 ThreadPoolExecutor
类实现的。ThreadPoolExecutor
是一个灵活的线程池实现,允许你调整线程池的大小,控制线程的生命周期,以及处理任务的策略。
以下是 ThreadPoolExecutor
的一些主要特性:
- 核心线程数 (Core Pool Size):线程池的基本大小,即即使线程处于空闲状态,也不会被销毁的线程数。
- 最大线程数 (Maximum Pool Size):线程池允许的最大线程数。当工作队列已满,并且已创建的线程数小于最大线程数时,线程池会再创建新的线程来处理任务。
- 存活时间 (Keep Alive Time):当线程数大于核心线程数时,这是多余空闲线程在终止前等待新任务的最长时间。
- 时间单位 (Time Unit):存活时间的单位,如
TimeUnit.SECONDS
表示秒。 - 工作队列 (Work Queue):用于保存待执行的任务的队列。常见的队列有
ArrayBlockingQueue
、LinkedBlockingQueue
、SynchronousQueue
等。 - 线程工厂 (Thread Factory):用于创建新线程的工厂。
- 拒绝策略 (Rejected Execution Handler):当线程池已关闭或达到最大线程数,且工作队列已满时,如何处理新提交的任务。常见的拒绝策略有
AbortPolicy
(直接抛出异常)、CallerRunsPolicy
(在调用者线程中运行任务)、DiscardOldestPolicy
(丢弃队列中最旧的任务,然后重新尝试执行任务)和DiscardPolicy
(不处理,直接丢弃任务)。
下面是一个简单的示例,展示如何创建一个固定大小的线程池:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExample {
public static void main(String[] args) {
// 创建一个固定大小的线程池
ExecutorService executor = Executors.newFixedThreadPool(5);
// 提交任务给线程池
for (int i = 0; i < 10; i++) {
Runnable task = () -> {
System.out.println(Thread.currentThread().getName() + " is running task " + i);
};
executor.submit(task);
}
// 关闭线程池
executor.shutdown();
}
}
在这个示例中,我们创建了一个大小为 5 的固定线程池,并向它提交了 10 个任务。由于线程池的大小为 5,因此只有 5 个任务可以并发执行,其余任务将等待前面的任务完成后才能执行。