Java并发编程:Executor框架

来源:互联网 发布:软件规模度量单位 编辑:程序博客网 时间:2020/11/25 15:45

Executor接口

在Java类库中,任务执行的主要抽象不是Thread,而是Executor,接口声明:

public interface Executor {    void execute(Runnable command);}

虽然Executor是个简单的接口,但它却为灵活且强大的异步任务执行框架提供了基础,该框架能支持多种不同类型的任务执行策略。它提供了一种标准的方法将任务的提交过程与执行过程解耦开来,并用Runnable来表示任务。Executor还提供了对生命周期的支持,以及统计信息收集、应用程序管理机制和性能监控等机制。

Executor基于生产者-消费者模式,提交任务的操作相当于生产者,执行任务的线程则相当于消费者。如果要在程序中实现一个生产者-消费者的设计,那么最简单的方式通常就是使用Executor。

每当看到下面这种形式的代码时:
new Thread(runnable).start()
并且希望获得一种更灵活的执行策略时,请使用Executor来代替Thread。

Executor的生命周期

由于Executor以异步的方式来执行任务,因此在任何时刻,之前提交的任务的状态不是立即可见的。为了解决执行服务的生命问题,Executor扩展了ExecutorService接口,添加了一些用于生命周期管理的方法(同时还有一些用于任务提交的便利方法)。ExecutorService接口声明:

public interface ExecutorService extends Executor {    void shutdown();    boolean isShutdown();    boolean isTerminated();    boolean awaitTermination(long timeout, TimeUnit unit)        throws InterruptedException;    <T> Future<T> submit(Callable<T> task);    <T> Future<T> submit(Runnable task, T result);    Future<?> submit(Runnable task);    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)        throws InterruptedException;    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,                                  long timeout, TimeUnit unit)        throws InterruptedException;    <T> T invokeAny(Collection<? extends Callable<T>> tasks)        throws InterruptedException, ExecutionException;    <T> T invokeAny(Collection<? extends Callable<T>> tasks,                    long timeout, TimeUnit unit)        throws InterruptedException, ExecutionException, TimeoutException;}

ExecutorService的生命周期有3种运行状态:运行、关闭和已终止。ExecutorService在初始创建时处于运行状态。shutdown方法将执行平缓的关闭过程:不再接受新的任务,同时等待已经提交的任务执行完成——包括那些还未开始的任务。shutdowNow方法将执行粗暴的关闭过程:它将尝试取消所有运行中的任务,并且不再启动队列中尚未开始执行的任务。

Executor的默认实现 —— AbstractExecutor

Executor,ExecutorService只是两个接口,抽象类AbstractExecutor实现了ExecutorService接口,基本实现了ExecutorService中声明的所有方法;

下面来看几个比较重要的方法的实现:

  • newTaskFor()方法:
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {        return new FutureTask<T>(callable);}

newTaskFor方法为callable任务返回了一个FutureTask对象。这个FutureTask对象运行时会调用底层的callable任务。 关于Callable、Future、及FutureTask相关内容可参看:Java并发
newTaskFor方法可由子类覆写。

  • submit()方法:
public <T> Future<T> submit(Callable<T> task) {        if (task == null) throw new NullPointerException();        RunnableFuture<T> ftask = newTaskFor(task);        execute(ftask);        return ftask;}

submit方法首先调用newTaskFor方法,返回一个RunnableFuture任务对象FutureTask,然后交给execute方法执行,上面说过FutureTask在执行时会调用传入的Callable任务,所以execute方法最终会执行传入的Callable任务。execute方法由继承AbstractExecutor的子类实现,最后将RunnableTask对象返回。

0 0