java 进阶笔记线程与并发之Executor、ExecutorService简析

简介

Executor和ExecutorService都是接口,他们主要完成一个工作:执行和管理任务。
即任务怎么运行、运行的结果、运行的统一启动与停止等等的管理。

在java中,一个任务在同步时通常是一个方法,一个逻辑片段。
但是更多情况,指的是异步执行的一段数据和逻辑。通常,我们将之封装为Thread,然后运行。
但是这样有一个缺点:即任务的执行、管理 和 任务的定义耦合了在一起。

Executor 简析

Executor 只是任务的提交和运行与任务的定义的解耦,对于任务组的管理则没有定义。

Executor 源码

/*
 * ORACLE 专有/保密. 使用以许可条款为准。
/*
 * 由Doug Lea在JCP JSR-166专家组成员的帮助下编写,
 * 并发布到公共领域,如http://creativecommons.org/publicdomain/zero/1.0/所述
 */

package java.util.concurrent;

/**
 *  这是个执行提交的Runnable任务的对象。
 * 这个接口提供了一个解耦的方法,即将任务提交和任务运行分离的机制,
 * 包括线程的使用、调度等。Executor被普通用于替代显示的线程的创建.
 * 例如,不想通过调用new Thread(new(RunnableTask())).start()来创建每个任务的话,
 * 你应该试试:
 *
 * Executor executor = anExecutor;
 * executor.execute(new RunnableTask1());
 * executor.execute(new RunnableTask2());
 * ...
 *
 * 然后,此接口并不严格要求执行必须是异步的,在一些简单情况下,
 * 一个执行者可以通过用户所在线程立即运行提交(的代码):
 *
 * class DirectExecutor implements Executor {
 *   public void execute(Runnable r) {
 *     r.run();
 *   }}
 *
 * 更多情况则是任务运行在其它的线程,而非用户调用线程。More typically, tasks are executed in some thread other
 * 执行者为每个任务新起一个线程:
 * class ThreadPerTaskExecutor implements Executor {
 *   public void execute(Runnable r) {
 *     new Thread(r).start();
 *    }
 * }}
 *
 * 许多Executor的实现对任务的调度方式和时间施加了某种限制。Many {@code Executor} implementations impose some sort of
 * 下面的执行器将任务的提交序列提交到第二个执行器,演示了复合执行器.
 * 自带示例:SerialExecutor  ( 单独提出,参见后文)

 * Executor同包下提供了一个实现类ExecutorService,
 * 它是一个更多功能扩展的接口。类ThreadPoolExecutor提供了一个线程池实现的扩展。
 * Executors类则提供了这些扩展的一些工厂方法。
 * 
 * 内存一致性效果: Runnable的提交一定发生在开始执行之前,执行可能是在另一个线程中。
 * @since 1.5
 * @author Doug Lea
 */
public interface Executor {
    /**
     * 在将来的某个时候执行给定的命令。
     * 该命令可以在新线程、线程池或调用线程中执行,由Executor的实现决定。
     *
     * @param command the runnable task
     * @throws RejectedExecutionException 如果无法接受此任务执行
     * @throws NullPointerException if command is null
     */
    void execute(Runnable command);
}

自带示例

import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.Executor;
//ps: 这是一个依赖于其它执行器的一个串行执行器
//它自身主要做一个队列的FIFO的功能,通过同步使任务顺序的提交到依赖的执行器
public class SerialExecutor implements Executor {
    final Queue<Runnable> tasks = new ArrayDeque<Runnable>();
    final Executor executor;
    Runnable active;

    SerialExecutor(Executor executor) {
        this.executor = executor;
    }

    public synchronized void execute(final Runnable r) {
        tasks.offer(new Runnable() {
            public void run() {
                try {
                    r.run();
                } finally {
                    scheduleNext();
                }
            }
        });
        if (active == null) {
            scheduleNext();
        }
    }

    protected synchronized void scheduleNext() {
        if ((active = tasks.poll()) != null) {
            executor.execute(active);
        }
    }
}

ExecutorService 简析

接口 java.util.concurrent.ExecutorService继承自Executor,主要扩展了对组任务的管理功能,
以及任务的执行状态跟踪。主要是通过传入Callable,返回Future来对任务的状态和结果做管理。

ps: 通过Executor的execute由于木有结果,所以其中的异常和中断需要自行处理,如果不处理,
则可能造成异常信息的丢失。
而对于ExecutorService 的submit与invoke机制,则返回Future,可以更有效的将“异步转为同步”,
异常处理可以放到调用者当前线程的结果处来处理,一般不会有异常丢失的情况发生。

源码

package java.util.concurrent;
import ava.util.List;
import java.util.Collection;

/**
 *这是一个Executor,它提供了管理终止的方法,以及能够产生Future来跟踪一个
 * 或者多个匿名任务的进度的方法。
 *
 * 一个ExecutorService 可以被shutdown,如此它会拒绝新任务。
 * submit方法将会创建并返回一个Future对象,它可以用于终止或者等待任务的完成。
 *
 *...省略一大段
 * 
 * 内存一致性:提交必须先于任务执行,任务执行happen-before Future.get()。 
 *
 * @since 1.5
 * @author Doug Lea
 */
public interface ExecutorService extends Executor {

    /**
     * 启动有序关闭,在此过程中执行先前提交的任务,但不接受任何新任务。
     * 如果已经关闭,调用不会产生额外的效果. 
     * 此方法立即执行,不阻塞,不等待以前提交的任务完成执行,如需要,
     * 使用方法awaitTermination完成阻塞等待。
     *
     * @throws SecurityException 如果存在安全管理器,且(想)修改用户不能修改的线程。
     */
    void shutdown();

    /**
     * 尝试停止所有正在执行的任务,停止等待任务的处理,并返回正在等待执行的任务列表。 
     * 不保证一定能立即停止正在执行的任务,例如,典型的实现将通过Thread.interrupt()取消,
     * 所以无法响应中断的任何任务永远不会终止。
     * @return list of tasks that never commenced execution
     * @throws SecurityException if...
     */
    List<Runnable> shutdownNow();

    /**
     * 这里返回的是此Executor是否关闭(而不是其中的任务)
     * @return {@code true} if this executor has been shut down
     */
    boolean isShutdown();

    /**
     * 返回所有的任务是否都关闭(或完成)
     *
     * @return {@code true} if all tasks have completed following shut down
     */
    boolean isTerminated();

    /**
     * 阻塞等待,直到以下几种情况之一发送则阻塞完毕: 
     * 1. 所有任务都完成或者关闭 
     * 2. 当前线程被中断 
     * 3. 超时
     * @param timeout the maximum time to wait
     * @param unit the time unit of the timeout argument
     * @return true = 时间内任务都全部执行完毕或者终止。
     *         false = 超时前任务还未执行完毕或终止。
     * @throws InterruptedException if interrupted while waiting
     */
    boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException;

    /**
     * 提交一个带有返回值的任务,返回一个未决结果的Future。
     * Future的get方法将会返回任务成功完成后的结果。
     *
     * 注意: Executors类包括一组方法,可以将一些其他常见的类似对象的对象,
     * 例如PrivilegedAction转换为Callable表单,以便它们可以提交。 
     * @param task the task to submit
     * @param <T> the type of the task's result
     * @return a Future representing pending completion of the task
     * @throws RejectedExecutionException if the task cannot be
     *         scheduled for execution
     * @throws NullPointerException if the task is null
     */
    <T> Future<T> submit(Callable<T> task);

    /**
     * Future.get()将在task执行完毕后返回给定的result对象。
     *
     * @param task the task to submit
     * @param result the result to return
     * @param <T> the type of the result
     * @return a Future representing pending completion of the task
     * @throws RejectedExecutionException if the task cannot be
     *         scheduled for execution
     * @throws NullPointerException if the task is null
     */
    <T> Future<T> submit(Runnable task, T result);

    /**
     * 提交一个可运行的任务执行,并返回一个表示该任务的未来。 成功完成时,Future.get()方法将返回null 
     *
     * @param task the task to submit
     * @return a Future representing pending completion of the task
     * @throws RejectedExecutionException if the task cannot be
     *         scheduled for execution
     * @throws NullPointerException if the task is null
     */
    Future<?> submit(Runnable task);

    /**
     * 执行给定的任务,当所有所有任务都完成时,返回一个Future列表来持有任务的状态和结果。
     * 返回的每个元素的Future.isDone is true。
     * 注意,一个完成的任务可以正常终止,也可以通过抛出异常终止。
     * 如果在执行此操作时修改了给定集合,则此方法的结果是未定义的。
     * 返回的任务的顺序就是传入的容器的迭代器元素的顺序。
     * @param tasks the collection of tasks
     * @param <T> the type of the values returned from the tasks
     * @return a list of Futures representing the tasks, in the same
     *         sequential order as produced by the iterator for the
     *         given task list, each of which has completed
     * @throws InterruptedException if interrupted while waiting, in
     *         which case unfinished tasks are cancelled
     * @throws NullPointerException if tasks or any of its elements are {@code null}
     * @throws RejectedExecutionException if any task cannot be
     *         scheduled for execution
     */
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException;

    /**
     * 当所有任务完成或者超时了,返回的列表中的每个Future.isDone is true。
     * 在返回之前,未完成的任务将会被取消。
     *
     * @param tasks the collection of tasks
     * @param timeout the maximum time to wait
     * @param unit the time unit of the timeout argument
     * @param <T> the type of the values returned from the tasks
     * @return a list of Futures representing the tasks, in the same
     *         sequential order as produced by the iterator for the
     *         given task list. If the operation did not time out,
     *         each task will have completed. If it did time out, some
     *         of these tasks will not have completed.
     * @throws InterruptedException if interrupted while waiting, in
     *         which case unfinished tasks are cancelled
     * @throws NullPointerException if tasks, any of its elements, or
     *         unit are {@code null}
     * @throws RejectedExecutionException if any task cannot be scheduled
     *         for execution
     */
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                  long timeout, TimeUnit unit)
        throws InterruptedException;

    /**
     * 执行给定任务,返回一个完成的结果。返回前,尚未完成的任务将被取消。
     * ps:并未说明实际执行的任务数量,估计留给子类处理。
     * @param tasks the collection of tasks
     * @param <T> the type of the values returned from the tasks
     * @return the result returned by one of the tasks
     * @throws InterruptedException if interrupted while waiting
     * @throws NullPointerException if tasks or any element task
     *         subject to execution is {@code null}
     * @throws IllegalArgumentException if tasks is empty
     * @throws ExecutionException if no task successfully completes
     * @throws RejectedExecutionException if tasks cannot be scheduled
     *         for execution
     */
    <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException;

    /**
     * 返回在指定时间内完成的一个任务结果。
     * @param tasks the collection of tasks
     * @param timeout the maximum time to wait
     * @param unit the time unit of the timeout argument
     * @param <T> the type of the values returned from the tasks
     * @return the result returned by one of the tasks
     * @throws InterruptedException if interrupted while waiting
     * @throws NullPointerException if tasks, or unit, or any element
     *         task subject to execution is {@code null}
     * @throws TimeoutException if the given timeout elapses before
     *         any task successfully completes
     * @throws ExecutionException if no task successfully completes
     * @throws RejectedExecutionException if tasks cannot be scheduled
     *         for execution
     */
    <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                    long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

最后

源码来自java8.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值