《Java并发编程的艺术》第十章 Executor框架

第十章 Executor 框架

从 JDK 1.5 开始,Java 将工作单元与执行机制分离开来。

工作单元包括 Runnable 和 Callable,而执行机制由 Executor 框架提供。

10.1 Executor 框架介绍

10.1.1 Executor 框架的两级调度模型

上层:Java 多线程程序通常把应用分解为若干个任务,然后使用用户级的调度器(Executor 框架)将这些任务映射为固定数量的线程。

底层:操作系统内核将这些线程映射到硬件处理器上。

10.1.2 Executor 框架结构与成员

1. Executor 框架的结构

Executor 框架主要由 3 部分组成:

  • 任务。包括被执行任务需要实现的接口:Runnable、Callable接口
    • Runnable 接口和 Callable 接口 都可以被 ThreadPoolExecutor 或 ScheduledThreadPoolExecutor 执行
  • 任务的执行。包括任务执行机制的核心接口 Executor,以及继承自 Executor 的 ExecutorService 接口。
    • Executor ,是 Executor 框架的基础,将任务的提交与任务的执行分离开来
    • ThreadPoolExecutor,是线程池的核心实现类,用来执行被提交的任务
    • ScheduledThreadPoolExecutor,可以在给定的延迟后运行命令,或者定期执行命令,比 Timer 更灵活、强大。
  • 异步计算的结果。包括接口 Future 和实现 Future 的 FutureTask 类
    • Future 接口和实现 Future 的 FutureTask 类,代表异步计算的结果。

主要流程为:

  1. 主线程创建实现 Runnable、Callable 接口的任务对象
  2. Executors 将 Runnable 对象封装为 Callable 对象
  3. 将 Runnable 对象交给 ExecutorService.execute(Runnable command) 执行,或者交给 ExecutorService.submit(Callable task) 执行
    1. 如果执行 submit,则 ExecutorService 返回一个实现 Future 接口的对象。
    2. 由于 FutureTask 实现了 Runnable,因此FutureTask 也可以直接交给 ExecutorService 执行
  4. 主线程执行 FutureTask.get() 方法等待任务执行完成;或者执行 FutureTask.cancel(boolean mayInterruptIfRunning) 来取消任务执行

2. Executor 框架的成员

  1. ThreadPoolExecutor:通常由工厂类 Executors 创建,可创建以下 3 种类型的ThreadPoolExecutor
    1. FixedThreadPool:创建使用固定线程数的ThreadPool,适用于需要限制当前线程数量的应用场景,适用于负载较重的服务器。
    2. SingleThreadExecutor:创建使用单个线程的 ThreadPool,适用于需要顺序执行各个任务;且在任意时间点,不会有多个线程是活动的应用场景
    3. CachedThreadPool:创建一个会根据需要创建新线程的 ThreadPool,是大小无界的线程池,适用于执行很多的短期异步任务的小程序,或者是负载较轻的服务器。
  2. ScheduledThreadPoolExecutor:通常由工厂类 Executors 创建,可创建以下 2 种类型的 ScheduledThreadPoolExecutor
    1. ScheduledThreadPoolExecutor,包含若干线程,适用于需要多个后台线程周期执行任务,同时需要限制后台线程数量的场景
    2. SingleThreadScheduledExecutor,只包含一个线程,适用于需要单个后台线程执行周期任务,同时需要保证顺序执行各个任务的应用场景
  3. Future/FutureTask:表示异步计算的结果
  4. Runnable/Callable:被 ThreadPoolExecutor 执行的任务。
    1. Runnable 不返回结果
    2. Callable 返回结果

10.2 ThreadPoolExecutor 详解

  • corePool:核心线程池的大小

  • maximumPool:最大线程池大小

  • BlockingQueue:阻塞队列,用来暂存任务的工作队列

  • RejectedExecutionHandler:拒绝策略,当 ThreadPoolExecutor 关闭或饱和时,将要调用的 Handler

文章作者: koral
文章链接: http://luokaiii.github.io/2019/06/05/读书笔记/《Java并发编程的艺术》/10.Executor框架/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自