跳到主要内容

Java 中的线程池是如何实现 ?

参考答案:

Java 中的线程池是通过 java.util.concurrent 包中的 ThreadPoolExecutor 类实现的。ThreadPoolExecutor 是一个灵活的线程池实现,允许你调整线程池的大小,控制线程的生命周期,以及处理任务的策略。

以下是 ThreadPoolExecutor 的一些主要特性:

  1. 核心线程数 (Core Pool Size):线程池的基本大小,即即使线程处于空闲状态,也不会被销毁的线程数。
  2. 最大线程数 (Maximum Pool Size):线程池允许的最大线程数。当工作队列已满,并且已创建的线程数小于最大线程数时,线程池会再创建新的线程来处理任务。
  3. 存活时间 (Keep Alive Time):当线程数大于核心线程数时,这是多余空闲线程在终止前等待新任务的最长时间。
  4. 时间单位 (Time Unit):存活时间的单位,如 TimeUnit.SECONDS 表示秒。
  5. 工作队列 (Work Queue):用于保存待执行的任务的队列。常见的队列有 ArrayBlockingQueueLinkedBlockingQueueSynchronousQueue 等。
  6. 线程工厂 (Thread Factory):用于创建新线程的工厂。
  7. 拒绝策略 (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 个任务可以并发执行,其余任务将等待前面的任务完成后才能执行。