Java并发编程:Executor框架

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对象返回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值