java多线程的Executor中定义了一个execut方法,ExecutorService接口继承了Executor接口,并进行了功能的扩展组合,定义了shutdown,shutdownNow,submit,invokeAll,invokeAny;而AbstractExecutorService类是一个模板类,实现了ExecutorService接口,对于公共行为进行了实现,同时对于具体的行为采用钩子函数的形式交由子类实现,它主要定义了invokeAll,invokeAny方法,具体的execute方法交由子类进行实现。

Executor接口:

一个执行提交任务的接口,只定义了一个执行任务的接口,入参为一个Runnable任务。ThreadPoolExecutor类提供一个可扩展的线程池实现。Executors类为这些executor提供了方便的工厂方法。

public interface Executor {
// 在将来的某个时间执行给定的命令。命令可以在一个新线程中执行,在一个池线程中执行,或者在调用线程中执行,由Executor实现决定。
void execute(Runnable command);
}

ExecutorService接口:

public interface ExecutorService extends Executor {

    /**
* 启动一个有序的关闭,在此关闭中执行先前提交的任务,但不接受新的任务。如果已经关闭,则调用没有额外的效果。此方法不等待先前提交的任务完成执行。使用awaitTermination来实现。
*/
void shutdown(); /**
* 尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表。此方法不会等待主动执行的任务终止。 使用awaitTermination来做到这一点。
*/
List<Runnable> shutdownNow(); /**
* 如果此执行程序已关闭,则返回true。
*/
boolean isShutdown(); /**
* 如果关闭后所有任务都已完成,则返回true。请注意,除非先调用shutdown或shutdownNow,否则isTerminated永远不会true。
*/
boolean isTerminated(); /**
* 阻塞直到所有任务在关闭请求后完成执行,或发生超时,或当前线程被中断,以先发生者为准。
*/
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException; /**
* 执行带返回值的任务
*/
<T> Future<T> submit(Callable<T> task); /**
* 提交一个 Runnable 任务以供执行,并返回一个代表该任务的 Future。
*/
<T> Future<T> submit(Runnable task, T result); /**
* 提交一个 Runnable 任务以供执行,并返回一个代表该任务的 Future。 Future 的get方法将在成功完成后返回null。
*/
Future<?> submit(Runnable task); /**
* 执行给定的任务,返回一个 Futures 列表,在所有完成时保存它们的状态和结果。
*/
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException; /**
* 执行给定的任务,当全部完成或超时到期时,返回一个保存其状态和结果的 Futures 列表,以先发生者为准。
*/
<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;
}

AbstractExecutorService类:

public abstract class AbstractExecutorService implements ExecutorService {

    /**
* 为给定的可运行和默认值返回RunnableFuture。
*/
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
} /**
* 为给定的可调用任务返回RunnableFuture。
*/
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
} public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
} public <T> Future<T> submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
} public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
} /**
* 主要操作步骤
*/
private <T> T doInvokeAny(Collection<? extends Callable<T>> tasks,
boolean timed, long nanos)
throws InterruptedException, ExecutionException, TimeoutException {
// 判空
if (tasks == null)
throw new NullPointerException();
int ntasks = tasks.size();
if (ntasks == 0)
throw new IllegalArgumentException();
ArrayList<Future<T>> futures = new ArrayList<>(ntasks); //任务结果集合
// 线程池包装器
ExecutorCompletionService<T> ecs = new ExecutorCompletionService<T>(this);
try { ExecutionException ee = null;
final long deadline = timed ? System.nanoTime() + nanos : 0L;
Iterator<? extends Callable<T>> it = tasks.iterator(); // 首先开启一项任务
futures.add(ecs.submit(it.next()));
--ntasks;
int active = 1; for (;;) {
Future<T> f = ecs.poll(); // 轮询
if (f == null) {
// 如果还有任务未执行,则继续提交一个任务执行,待执行任务数减一,活跃数加一
if (ntasks > 0) {
--ntasks;
futures.add(ecs.submit(it.next()));
++active;
} // 如果活跃数为0,跳出循环,
else if (active == 0)
break;
else if (timed) { // 如果设置了延时,则进行延时轮询
f = ecs.poll(nanos, NANOSECONDS);
if (f == null) // 延时轮询后获取不到结果,则抛出超时异常
throw new TimeoutException();
nanos = deadline - System.nanoTime();
}
else
f = ecs.take(); // 阻塞获取
}
if (f != null) {
--active; //活跃数减一
try {
return f.get(); //返回结果值
} catch (ExecutionException eex) {
ee = eex;
} catch (RuntimeException rex) {
ee = new ExecutionException(rex);
}
}
} if (ee == null)
ee = new ExecutionException();
throw ee; } finally {
cancelAll(futures); // 取消执行任务
}
} public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException {
try {
return doInvokeAny(tasks, false, 0);
} catch (TimeoutException cannotHappen) {
assert false;
return null;
}
} public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
return doInvokeAny(tasks, true, unit.toNanos(timeout));
} public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException {
if (tasks == null) // 判空
throw new NullPointerException();
ArrayList<Future<T>> futures = new ArrayList<>(tasks.size());
try { // 执行所有的任务
for (Callable<T> t : tasks) {
RunnableFuture<T> f = newTaskFor(t);
futures.add(f);
execute(f);
}
for (int i = 0, size = futures.size(); i < size; i++) {
Future<T> f = futures.get(i);
if (!f.isDone()) { // 如果任务未完成,则阻塞等待任务完成
try { f.get(); }
catch (CancellationException | ExecutionException ignore) {}
}
}
return futures; // 返回结果集
} catch (Throwable t) {
cancelAll(futures); // 取消执行任务
throw t;
}
} public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException {
if (tasks == null)
throw new NullPointerException();
final long nanos = unit.toNanos(timeout);
final long deadline = System.nanoTime() + nanos;
ArrayList<Future<T>> futures = new ArrayList<>(tasks.size());
int j = 0;
timedOut: try {
for (Callable<T> t : tasks)
futures.add(newTaskFor(t)); final int size = futures.size(); // 如果超时,则跳出循环
for (int i = 0; i < size; i++) {
if (((i == 0) ? nanos : deadline - System.nanoTime()) <= 0L)
break timedOut;
execute((Runnable)futures.get(i));
} for (; j < size; j++) {
Future<T> f = futures.get(j);
if (!f.isDone()) { // 若任务未完成,则延时等待
try { f.get(deadline - System.nanoTime(), NANOSECONDS); }
catch (CancellationException | ExecutionException ignore) {}
catch (TimeoutException timedOut) {
break timedOut;
}
}
}
return futures;
} catch (Throwable t) {
cancelAll(futures); // 取消执行任务
throw t;
}
cancelAll(futures, j); // 取消执行任务
return futures;
} private static <T> void cancelAll(ArrayList<Future<T>> futures) {
cancelAll(futures, 0);
} private static <T> void cancelAll(ArrayList<Future<T>> futures, int j) {
for (int size = futures.size(); j < size; j++)
futures.get(j).cancel(true);
}
}

JUC之Executor,ExecutorService接口,AbstractExecutorService类的更多相关文章

  1. JUC中Executor基本知识

    Future And Callable 引用 http://www.cnblogs.com/dolphin0520/p/3949310.html http://www.iocoder.cn/JUC/ ...

  2. Java 并发:Executor ExecutorService ThreadPoolExecutor

    Executor Executor仅仅是一个简单的接口,其定义如下 public interface Executor { void execute(Runnable command); } 作为一个 ...

  3. java并发编程框架 Executor ExecutorService invokeall

    首先介绍两个重要的接口,Executor和ExecutorService,定义如下: public interface Executor { void execute(Runnable command ...

  4. Executor, ExecutorService 和 Executors 间的区别与联系

    UML简要类图关系: 下面详细看一下三者的区别: Executor vs ExecutorService vs Executors 正如上面所说,这三者均是 Executor 框架中的一部分.Java ...

  5. Executor, ExecutorService 和 Executors 间的不同

    java.util.concurrent.Executor, java.util.concurrent.ExecutorService, java.util.concurrent. Executors ...

  6. ExecutorService接口概要

    ExecutorService接口继承于Executor接口,主要提供以下额外功能: 管理终结 产生Future对象,用于跟踪一个或多个任务的进度.   ExecutorService可以被shut ...

  7. Executor ExecutorService Executors

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

  8. ExecutorService 接口

    先看一个Executor接口,该接口只有一个方法:void execute(Runnable command),用于在未来某个时刻提交一个command,这个command可以被提交到一个新的线程,或 ...

  9. 聊聊高并发(三十九)解析java.util.concurrent各个组件(十五) 理解ExecutorService接口的设计

    上一篇讲了Executor接口的设计,目的是将任务的运行和任务的提交解耦.能够隐藏任务的运行策略.这篇说说ExecutorService接口.它扩展了Executor接口,对Executor的生命周期 ...

随机推荐

  1. jQuery中的筛选(六):first()、last()、has()、is()、find()、siblings()等

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...

  2. jQuery中ajax请求的六种方法(三、六):load()方法

    6.load()方法 load的html页面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8& ...

  3. linux 常用命令(三)——(centos7)MySql 5.7添加用户、删除用户与授权

    一.创建用户:以root用户登录到数据库进行用户创建 命令: CREATE USER 'username'@'host' IDENTIFIED BY 'password'; 例如: CREATE US ...

  4. 了解Flask

    了解Flask 什么是Flask Flask 是一个微框架(Micro framework),所谓微框架,它就是很轻量级的,作者划分出了Flask应该负责什么(请求路由.处理请求.返回响应).不应该负 ...

  5. redis rpoplpush列表转移元素

    文档出处:redisdoc.com/list/rpoplpush.html模式: 安全的队列 Redis的列表经常被用作队列(queue),用于在不同程序之间有序地交换消息(message).一个客户 ...

  6. IDEA常用设置及推荐插件

    IDEA常用设置及推荐插件 本文主要记录IDEA的一些常用设置,IDEA与Eclipse的常用快捷键对比及推荐一些好用的插件. 基本设置 设置界面风格及修改外部UI尺寸大小 打开IDEA时设置不重新打 ...

  7. ECMAScript版本知识点汇总

    ECMAScript版本知识点汇总 ES5 btoa.atob 对参数进行base64格式编码.解码 /** * btoa() * base64编码 * @param {string} str * @ ...

  8. redis跨实例迁移 & redis上云

    1)redis跨实例迁移--源实例db11迁移至目标实例db30 root@fe2e836e4470:/data# redis-cli -a pwd1 -n 11 keys \* |while rea ...

  9. 前后端数据交互(八)——请求方法 GET 和 POST 区别

    WEB 开发同学一看 get 和 post 请求方法的区别,第一感觉都是 So easy! 学习ajax.fetch.axios时,发送网络请求携带参数时,都需要分别处理get和post的参数.所以我 ...

  10. tar解压缩问题

    gzip: stdin: unexpected end of filetar: 归档文件中异常的 EOFtar: 归档文件中异常的 EOFtar: Error is not recoverable: ...