JUC之Executor,ExecutorService接口,AbstractExecutorService类
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类的更多相关文章
- JUC中Executor基本知识
Future And Callable 引用 http://www.cnblogs.com/dolphin0520/p/3949310.html http://www.iocoder.cn/JUC/ ...
- Java 并发:Executor ExecutorService ThreadPoolExecutor
Executor Executor仅仅是一个简单的接口,其定义如下 public interface Executor { void execute(Runnable command); } 作为一个 ...
- java并发编程框架 Executor ExecutorService invokeall
首先介绍两个重要的接口,Executor和ExecutorService,定义如下: public interface Executor { void execute(Runnable command ...
- Executor, ExecutorService 和 Executors 间的区别与联系
UML简要类图关系: 下面详细看一下三者的区别: Executor vs ExecutorService vs Executors 正如上面所说,这三者均是 Executor 框架中的一部分.Java ...
- Executor, ExecutorService 和 Executors 间的不同
java.util.concurrent.Executor, java.util.concurrent.ExecutorService, java.util.concurrent. Executors ...
- ExecutorService接口概要
ExecutorService接口继承于Executor接口,主要提供以下额外功能: 管理终结 产生Future对象,用于跟踪一个或多个任务的进度. ExecutorService可以被shut ...
- Executor ExecutorService Executors
Executor public interface Executor { void execute(Runnable command); } ExecutorService ExecutorServi ...
- ExecutorService 接口
先看一个Executor接口,该接口只有一个方法:void execute(Runnable command),用于在未来某个时刻提交一个command,这个command可以被提交到一个新的线程,或 ...
- 聊聊高并发(三十九)解析java.util.concurrent各个组件(十五) 理解ExecutorService接口的设计
上一篇讲了Executor接口的设计,目的是将任务的运行和任务的提交解耦.能够隐藏任务的运行策略.这篇说说ExecutorService接口.它扩展了Executor接口,对Executor的生命周期 ...
随机推荐
- Java同步之线程池详解
带着问题阅读 1.什么是池化,池化能带来什么好处 2.如何设计一个资源池 3.Java的线程池如何使用,Java提供了哪些内置线程池 4.线程池使用有哪些注意事项 池化技术 池化思想介绍 池化思想是将 ...
- adb 常用命令大全(4)- 应用管理
查看应用列表 语法格式 adb shell pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user USER_ID] [FILTER] ...
- JUnit5 快速入门指南
1. 安装 在pom中添加依赖 <properties> <junit.jupiter.version>5.3.2</junit.jupiter.version> ...
- Identity基于角色的访问授权
详情访问官方文档 例如,以下代码将访问权限限制为属于角色成员的用户的任何操作 AdministrationController Administrator : [Authorize(Roles = & ...
- gitlab安装CI问题汇总
0.设置gitlab获取代码的存放位置 vim /etc/gitlab-runner/config.toml 1.unable to access http://gitlab-ci-token:xxx ...
- systemctl --now参数
1.我们安装一个httpd服务来测试一下 --now参数 yum install httpd 2.查看一下当前服务状态 可以看到服务没有启动 而且服务没有自启 [root@master1 ~]# s ...
- 记录一次C语言中free(p)失败
首先介绍一下自己的程序出错的原因,然后总结一下什么时候free会失败. 1.程序伪代码 // 已知payload已经指向一部分内存数据 char * payload; int payload_len; ...
- error: subscripted value is neither array nor pointer问题解决
在运行程序的时候报错:error: subscripted value is neither array nor pointer 原因分析:下标值不符合数组或指针要求,即操作的对象不允许有下标值. 出 ...
- PHP匿名类的用法
在PHP7之后,PHP中加入了匿名类的特性.匿名类和匿名方法让PHP成为了更现代化的语言,也让我们的代码开发工作越来越方便.我们先来看看匿名类的简单使用. // 直接定义 $objA = new cl ...
- Docker系列(13)- 部署es+kibana
部署elasticsearch # es 暴露的端口很多 # es 十分的消耗内存 # es 的数据一帮需要放置到安全目录!通过挂载实现 # DockerHub上安装文档,其中 --net somen ...