线程池系列(五):线程池总结

Posted by 陈树义 on 2021-06-16

线程池一共有 3 块体系化的东西,分别是:

  • executor 接口体系
  • future 接口体系
  • callable 接口体系

executor接口体系

下面是整个 executor 接口体系的类结构图。

其中绿色部分是定义的接口,红色部分是线程池的核心实现类,黄色部分是非核心实现类。

接口定义

executor 接口体系定义了线程池的整体框架,所有其他实现都是在这些接口的基础上进行实现。从上面类图的绿色部分可以看出,executor 接口体系有 3 个主要接口:

  1. Executor:提交普通的可执行任务
  2. ExecutorService:提供对线程池生命周期的管理、异步任务的支持
  3. ScheduledExecutorService:提供对任务的周期性执行支持

核心实现

线程池的核心实现是所有线程池的实现基础,包括固定线程池、缓存线程池、单线程池等都必须依赖此实现。从上面类图的红色部分可以看出,线程池的核心实现有这么几个类:

  • AbstractExecutorService:线程池的抽象实现,实现了通用的方法。
  • ThreadPoolExecutor:通用线程池实现,基本涵括了绝大多数线程池的实现。
  • ScheduledThreadPoolExecutor:调度线程池的实现,在 ThreadPoolExecutor 的基础上提供了对任务周期性的执行支持。

非核心实现

线程池的非核心实现主要是为了满足单线程池的实现,即 SingleThreadExecutor 和 SingleThreadScheduledExecutor 的实现。从上面类图的黄色部分可以看出,最上层的是 DelegatedExecutorService 类,其有 FinalizableDelegatedExecutorService 和 DelegatedScheduledExecutorService 两个子类。

  • DelegatedExecutorService类:线程池的代理实现。本身并不直接实现线程池的逻辑,而是通过传入的 ExecutorService 对象实现的。
  • FinalizableDelegatedExecutorService 类:是单线程池的外层包装实现(SingleThreadExecutor),其核心通过 DelegatedExecutorService 实现。
  • DelegatedScheduledExecutorService 类:是单线程调度池的外层包装实现(SingleThreadScheduledExecutor),其核心通过 DelegatedExecutorService 实现。

future 接口体系

下面是整个 future 接口体系的类结构图。

接口定义

在 future 定义的接口中,有三个最为基础的接口:

  • Runnable 接口:是一个线程最基本的接口,任何一个线程都必须实现这个接口。
  • Future 接口:提供异步操作的接口。
  • Delayed 接口:提供延迟调度的接口。

上面三个基础接口通过一定的组合又形成了新的接口:

  • RunnableFuture 接口:线程+异步,那么就是可以异步获取结果的线程。
  • ScheduledFuture 接口:异步+延迟,那么就是延迟调度异步获取结果的线程。

而上面两个接口进行组合,又形成了新的接口:

  • RunnableScheduledFuture 接口:它实现了上述的 RunnableFuture 和ScheduledFuture 接口,也就是实现了线程+异步+调度的功能。

核心实现

Future 接口体系主要有两个非常核心的实现:

  • FutureTask:它是 RunnableFuture 的实现类,其可以实现线程+异步获取的功能。线程池中除了调度线程池外,都是使用 FutureTask 作为放入线程池的任务。
  • ScheduledTutureTask:它是 RunnableScheduledFuture 接口的具体实现,也就是可以实现线程+异步+调度的功能。它在线程池实现中作为调度线程池的任务对象放入线程池。从类结构图可以看出,其继承了 FutureTask 的实现。,但是其底层也是使用 FutureTask 实现的。

callable 接口体系

除了上面这些接口之外,其实还有一个接口非常重要,那就是:Callable 接口以及其在线程池中的实现:RunnableAdapter。

Callable 接口是最终用于获取结果的接口,其定义了 call 方法返回一个最终值。

public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

ThreadPoolExecutor 的内部实现是将线程封装成一个个 FutureTask 对象,而 FutureTask 对象内部则是通过 RunnableAdapter 对象实现的。

// AbstractExecutorService 中的抽象实现
public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask); // 调用子类 ThreadPoolExecutor 的模板方法运行
    return ftask;
}
// 运行的 ftask 是一个 FutureTask 对象
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
    return new FutureTask<T>(runnable, value);
}
// FutureTask 最终用 callable 对象封装
public FutureTask(Runnable runnable, V result) {
    this.callable = Executors.callable(runnable, result);
    this.state = NEW;       // ensure visibility of callable
}
public static <T> Callable<T> callable(Runnable task, T result) {
    if (task == null)
        throw new NullPointerException();
    return new RunnableAdapter<T>(task, result);
}

总结