Executor 框架简介

目录

Executor 框架的两级调度模型 

Executor 框架的结构与成员

1) Executor 框架的结构

2) Executor 框架的成员

ThreadPoolExecutor


        Java 的线程既是工作单元,也是执行机制。从 JDK 5 开始,把工作单元与执行机制分离开来。工作单元包括 Runnable 和 Callable,而执行机制由 Executor 框架提供。

Executor 框架的两级调度模型 

        在 HotSpot VM 的线程模型中,Java 线程(java.lang.Thread)被一对一映射为本地操作系统线程。Java 线程启动时会创建一个本地操作系统线程;当该 Java 线程终止时,这个操作系统线程也会被回收。操作系统会调度所有线程并将它们分配给可用的 CPU。

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

        在底层,操作系统内核将这些线程映射到硬件处理器上。这种两级调度模型的示意图如图 10-1 所示。

 

        从图中可以看出,应用程序通过 Executor 框架控制上层的调度;而下层的调度由操 作系统内核控制,下层的调度不受应用程序的控制。 

Executor 框架的结构与成员

1) Executor 框架的结构

        Executor 框架主要由 3 大部分组成如下。

  1.  任务:包括被执行任务需要实现的接口:Runnable 接口或 Callable 接口。
  2. 任务的执行:包括任务执行机制的核心接口 Executor,以及继承自 Executor 的 ExecutorService 接口。Executor 框架有两个关键类实现了 ExecutorService 接口 (ThreadPoolExecutor 和 ScheduledThreadPoolExecutor)。
  3. 异步计算的结果:包括接口 Future 和实现 Future 接口的 FutureTask 类。

Executor 框架包含的主要的类与接口如图所示。 下面是这些类和接口的简介。

  • Executor 是一个接口,它是 Executor 框架的基础,它将任务的提交与任务的执行分离开来。
  • ThreadPoolExecutor 是线程池的核心实现类,用来执行被提交的任务。
  • ScheduledThreadPoolExecutor 是一个实现类,可以在给定的延迟后运行命令,或者定期执行命令。ScheduledThreadPoolExecutor 比 Timer 更灵活,功能更强大。
  • Future 接口和实现 Future 接口的 FutureTask 类,代表异步计算的结果。
  • Runnable 接口和 Callable 接口的实现类,都可以被 ThreadPoolExecutor 或    ScheduledThreadPoolExecutor 执行。

主线程首先要创建实现 Runnable 或者 Callable 接口的任务对象。

工具类 Executors 可以把一个 Runnable 对象封装为一个 Callable 对象(Executors.callable(Runnable task)或 Executors.callable(Runnable task,Object resule))。

 然后可以把 Runnable 对象直接交给 ExecutorService 执行(ExecutorService.execute (Runnable command));或者也可以把 Runnable 对象或 Callable 对象提交给 ExecutorService 执行(Executor-Service.submit(Runnable task)或 ExecutorService.submit (Callabletask))。

如果执行 ExecutorService.submit(…),ExecutorService 将返回一个实现 Future 接口的对象(到目前为止的 JDK 中,返回的是 FutureTask 对象)。由于 FutureTask 实现了 Runnable,程序员也可以创建 FutureTask,然后直接交给 ExecutorService 执行。

最后,主线程可以执行 FutureTask.get()方法来等待任务执行完成。主线程也可以执行 FutureTask.cancel(boolean mayInterruptIfRunning)来取消此任务的执行         

2) Executor 框架的成员

(1)ThreadPoolExecutor

        ThreadPoolExecutor 通常使用工厂类 Executors 来创建。Executors 可以创建 3 种类型的 ThreadPoolExecutor:SingleThreadExecutor、FixedThreadPool 和 CachedThreadPool。

1.  FixedThreadPool。下面是 Executors 提供的,创建使用固定线程数的 FixedThreadPool 的 API。

public static ExecutorService newFixedThreadPool(int nThreads) 
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) 

FixedThreadPool适用于为了满足资源管理的需求,而需要限制当前线程数量的应用场景,它适用于负载比较重的服务器。

2. SingleThreadExecutor。下面是 Executors 提供的,创建使用单个线程的 SingleThread-Executor 的 API。

public static ExecutorService newSingleThreadExecutor() 
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) 

SingleThreadExecutor 适用于需要保证顺序地执行各个任务;并且在任意时间点,不会有多个线程是活动的应用场景。

3. CachedThreadPool。下面是 Executors 提供的,创建一个会根据需要创建新线程的 CachedThreadPool 的 API。

public static ExecutorService newCachedThreadPool() 
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) 

CachedThreadPool 是大小无界的线程池,适用于执行很多的短期异步任务的小程序,或者是负载较轻的服务器。

(二)  ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor 通常使用工厂类 Executors 来创建。

Executors 可以创建 2 种类型的 ScheduledThreadPoolExecutor。

         • ScheduledThreadPoolExecutor。包含若干个线程 ScheduledThreadPoolExecutor。

         • SingleThreadScheduledExecutor。只包含一个线程 ScheduledThreadPoolExecutor。

创建固定个数线程的 ScheduledThreadPoolExecutor 的 API。

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory) 

ScheduledThreadPoolExecutor 适用于需要多个后台线程执行周期任务,同时为了满足资源管理的需求而需要限制后台线程的数量的应用场景。

创建单个线程的 SingleThreadScheduledExecutor 的 API。

public static ScheduledExecutorService newSingleThreadScheduledExecutor()
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory)

SingleThreadScheduledExecutor 适用于需要单个后台线程执行周期任务,同时需要保证顺序地执行各个任务的应用场景。

(三) Future 接口

Future 接口和实现 Future 接口的 FutureTask 类用来表示异步计算的结果。

当我们把 Runnable 接口或 Callable 接口的实现类提交(submit)给 ThreadPoolExecutor 或 ScheduledThreadPoolExecutor 时,ThreadPoolExecutor 或 ScheduledThreadPoolExecutor 会 向我们返回一个 FutureTask 对象。

下面是对应的 API。

Future submit(Callable task) 
Future submit(Runnable task, T result) 
Future<> submit(Runnable task)

从 API 可以看到,Java 仅仅保证返回的是一个实现了 Future 接口的 对象。在将来的 JDK 实现中,返回的可能不一定是 FutureTask。

(四) Runnable 接口和 Callable 接口

Runnable 接口和 Callable 接口的实现类,都可以被 ThreadPoolExecutor 或 ScheduledThreadPoolExecutor 执行。它们之间的区别是 Runnable 不会返回结果,而 Callable 可以返回结果

除了可以自己创建实现 Callable 接口的对象外,还可以使用工厂类 Executors 来把一 个 Runnable 包装成一个 Callable。

// 把一个 Runnable 包装成一个 Callable 的 API。

public static Callable callable(Runnable task) // 假设返回对象 Callable1
// 把一个 Runnable 和一个待返回的结果包装成一个 Callable 的 API。 
public static Callable callable(Runnable task, T result) // 假设返回对象 Call 

        当我们把一个 Callable 对象(比如上面的 Callable1 或 Callable2)提交给 ThreadPoolExecutor 或 ScheduledThreadPoolExecutor 执行时,submit(…)会向我们返回 一个 FutureTask 对象。

        我们可以执行 FutureTask.get()方法来等待任务执行完成。当任务成功完成后 FutureTask.get()将返回该任务的结果。例如,如果提交的是对象 Callable1, FutureTask.get()方法将返回 null;如果提交的是对象 Callable2,FutureTask.get()方法将返回 result 对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值