Java线程执行机制“Executor 框架”

背景简介

    在 Java 中,使用线程来异步执行任务。 Java 线程的创建与销毁需要一定的开销,如果我们为每一个任务创建一个新线程来执行,这些线程的创建与销毁将消耗大量的计算资源。同时,为每一个任务创建一个新线程来执行,这种策略可能会使处于高负荷状态
的应用最终崩溃。
      Java 的线程既是工作单元,也是执行机制。从 JDK 5 开始,把工作单元与执行机制分离开来。工作单元包括 Runnable Callable ,而执行机制由 Executor 框架提供。

Executor 框架的结构与成员

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

下面是这些类和接口的简介

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

              

主线程首先要创建实现 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(Callable<T>task ))。
如果执行 ExecutorService.submit( ), ExecutorService 将返回一个实现 Future 接口的对象(到目前为止的 JDK 中,返回的是 FutureTask 对象)。由于 FutureTask 实现了Runnable,程序员也可以创建 FutureTask ,然后直接交给 ExecutorService 执行。
最后,主线程可以执行 FutureTask.get()方法来等待任务执行完成。主线程也可以执行 FutureTask.cancel (boolean mayInterruptIfRunning)来取消此任务的执行。

Executor 框架的成员  

Executor 框架的主要成员: ThreadPoolExecutor、 ScheduledThreadPoolExecutor、Future 接口、 Runnable 接口、 Callable 接口和 Executors。
() 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(ThreadFactorythreadFactory)

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

(二) ScheduledThreadPoolExecutor(定期执行命令)
ScheduledThreadPoolExecutor 通常使用工厂类 Executors 来创建。 Executors 可以创建2 种类型
的 ScheduledThreadPoolExecutor ,如下。
ScheduledThreadPoolExecutor 。包含若干个线程 ScheduledThreadPoolExecutor
SingleThreadScheduledExecutor 。只包含一个线程 ScheduledThreadPoolExecutor
下面分别介绍这两种 ScheduledThreadPoolExecutor
下面是工厂类 Executors 提供的,创建固定个数线程的 ScheduledThreadPoolExecutor API
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize,
ThreadFactory threadFactory)
ScheduledThreadPoolExecutor 适用于需要多个后台线程执行周期任务,同时为了满足资源管理的需求而需要限制后台线程的数量的应用场景。
下面是 Executors 提供的,创建单个线程的 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
 
<T> Future<T> submit(Callable<T> task)
<T> Future<T> submit(Runnable task, T result)
Future<> submit (Runnable task) 有一点需要读者注意,到目前最新的 JDK 8 为止, Java 通过上述 API 返回的是一个
FutureTask 对象。但从 API 可以看到, Java 仅仅保证返回的是一个实现了 Future 接口的对象。在将来的 JDK 实现中,返回的可能不一定是 FutureTask

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值