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的生命周期 ...
随机推荐
- 多线程Synchronized的两种锁
Synchronized的作用: 能够保证在同一时刻最多只有一个线程执行该段代码,以达到保证并发安全的效果 Synchronized的两个用法: 1)对象锁 包括方法锁(默认锁对象为this当前实例对 ...
- Go与接口:接口即约定
接口 接口类型是对其他类型行为的概括与抽象.我们可以通过接口来约定某一类通用行为.Go语言的接口是隐式的:只要实现接口A的所有方法就代表实现了接口A. 接口即约定 接口是什么样的? package i ...
- 去除所有js,html,css代码
<?php$search = array ("'<script[^>]*?>.*?</script>'si", // 去掉 javascript ...
- MySQL-SQL基础-查询1
#子查询-某些情况下,当进行查询的时候,需要的条件是另外一个select语句的结果,这个时候就要用到子查询.用于子查询的关键字主要包括: in.not in.=.!=.exists.not exist ...
- Tomcat集群Cluster实现原理
1.Tomcat集群 Tomcat集群的问题之一是如何处理Session,Session是有状态的,请求到了Tomcat,后续流传是要根据上下文(Context)来进行的.我们可以改造 ...
- HTML一小时入门,半天掌握
还没有写完,后续持续更新 首先来熟悉一下html的基本结构 <!DOCTYPE HTML> <html> <head> <meta charset=" ...
- ms sql 带自增列 带外键约束 数据导入导出
1,生成建表脚本 选中要导的表,点右键-编写表脚本为-create到 ,生成建表脚本 2,建表(在新库),但不建外键关系 不要选中生成外键的那部分代码,只选择建表的代码 3,导数据,用SQL STU ...
- 运行FreeSWITCH的命令行参数
一般来说,FreeSWITCH 不需要任何命令行参数就可以启动,但在某些情况下,你需要以一些特殊的参数启动.在此,仅作简单介绍.如果你知道是什么意思,那么你就可以使用,如果不知道,多半你用不到. 使用 ...
- Wpf读写Xaml文件
前言 本文主要介绍Wpf读写Xaml文件. 读写实现 首先我们使用XamlWriter将Wpf的对象转换为Xaml字符串,代码如下: var btn = sender as Button; strin ...
- 使用vsCode开发vue项目格式化通用配置
{ "editor.tabSize": 2, "editor.fontSize": 18, "editor.wordWrap": ...