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的生命周期 ...
随机推荐
- php常用的函数
addslashes: 字符串加入斜线.bin2hex: 二进位转成十六进位.chop: 去除连续空白.chr: 返回序数值的字符.chunk_split: 将字符串分成小段.convert_cyr_ ...
- Python中的多线程编程
前言: 线程是操作系统能够进行运算调度的最小单位(程序执行流的最小单元) 它被包含在进程之中,是进程中的实际运作单位 一个进程中可以并发多个线程每条线程并行执行不同的任务 (线程是进程中的一个实体,是 ...
- UDP实现在线聊天功能
发送端 //发送 public class UDPChat01 { public static void main(String[] args) throws Exception { //开启端口 D ...
- golang context包
go context标准库 context包在Go1.7版本时加入到标准库中.其设计目标是给Golang提供一个标准接口来给其他任务发送取消信号和传递数据.其具体作用为: 可以通过context发送取 ...
- ASH数据的迁移:导出导入
自己写的小工具: 查看帮助 [oracle@redhat76 2]$ ./orash Usage: sh orash keyword [value1] [value2] --------------- ...
- Jenkins(8)- CentOS 7.x 通过yum安装jenkins
如果想从头学起Jenkins的话,可以看看这一系列的文章哦 https://www.cnblogs.com/poloyy/category/1645399.html 下载rpm包 sudo wget ...
- Spring Dependency Injection浅析
Dependency Injection 依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件. 1.在UserService中提供一个get/set的name方法, ...
- 测试开发【提测平台】分享9-DBUntils优化数据连接&实现应用搜索和分页功能
微信搜索[大奇测试开],关注这个坚持分享测试开发干货的家伙. 从本期开始知识点讲以思维导图的形式给出,内容点会按照讲解-应用-展示的形式体现,这样会更清晰些. DBUntils连接池 在项目中链接数据 ...
- Vue跨域问题解决
项目根目录下创建vue.config.js module.exports = { devServer: { proxy: { //配置跨域 '/api': { //这里是真实的后台接口 target: ...
- VUE001. 拖动div盒子(自定义指令v-directives)
拖动div是一个逻辑很简单的需求,监听容器的鼠标按下松开的事件,执行函数通过DOM改变标签的CSS偏移量. 在VUE构建的项目中,通过标签的 @mousedown 和 @mouseup 赋予行为事件, ...