Executor和ExecutorService分析

Executor

Executor中只定义了一个execute方法,可以通过execute方法向Executor中提交可运行的任务(实现Runnable接口)。方法的具体定义如下

void execute(Runnable command)

它提供了一种将任务的提交和任务运行之间的解耦机制。任务具体运行细节,可以有多种机制。在实现层面上,可以直接在提交任务的线程中运行此任务,也可以给每个提交的任务分配一个新的线程来执行,还可以将提交的任务放入到另外的一个Executor中去执行。

ExecutorService

ExecutorService是一个功能更为丰富的Executor,它本身继承了Executor接口。除了Executor接口本身具有的解耦任务提交和任务运行功能之外,还提供了终止任务功能,并提供了submit方法可以根据返回结果来跟踪任务运行的状态。

  1. submit方法

submit方法,可以用于任务提交。与execute不同的是,经过submit提交的Runnable或是Callable任务,能够返回Future对象。我们可以通过Future对象,来跟踪任务运行的状态。在任务运行结束之后,可以通过Future的get方法来获取任务运行的结果。在任务运行尚未结束的时候,调用get方法将会阻塞。

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

​ 2. shutdown和shutdownNow

ExecutorService提供了shutdown和shutdownNow方法用于关闭ExecutorService。关闭之后,将不能再向ExecutorService中提交新的任务。

shutdown和shutdownNow的区别在于调用shutdown之后,ExecutorService会等待原先已提交的任务执行完成。而shutdownNow调用之后,会阻止原来已提交的尚未开始执行的任务的开始执行,并且会尝试停止正在运行的任务。

其中,shutdownNow的定义如下

List<Runnable> shutdownNow();

调用shutdownNow方法的返回结果,是等待执行的方法的列表。

调用shutdown或是shutdownNow之后,方法isShutdown()将会返回true。

关于关闭ExecutorService的方法。在官方的注释中,提供了如下的代码编写方式

void shutdownAndAwaitTermination(ExecutorService pool) {
    pool.shutdown();
    try {
        if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
            pool.shutdownNow();
            if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
                System.err.println("Pool did not terminate");
            }
        }
    } catch (InterruptedException ie) {
        pool.shutdownNow();
        Thread.currentThread.interrupt();
    }
}
  1. isTerminated

terminated是这样一种状态,当调用shutdown或是shutdownNow方法之后,当Executor中没有正在执行的任务,没有等待执行的任务时。

如果以上的状态成立,调用isTerminated(),将会返回true。

  1. awaitTermination

    与isTerminated()方法类似,awaitTermination方法一般在调用shutdown或是shutdownNow方法之后,用于等待所有的任务执行完毕。它会阻塞线程,直到所有的任务执行完成或是等待时间超时。

    boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException
    
  2. invoke

在ExecutorService中提供了invokeAll和invokeAny方法。根据是否可以设置超时时间,每个方法都包含了两个不同的版本。invokeAll方法,执行所有的任务,并返回代表执行任务结果的Future。invokeAny方法,执行所有的任务,返回一个执行完成的任务的结果。

Comments
Write a Comment