public abstract class ForkJoinTask<V> extends Object implements Future<V>, Serializable
ForkJoinPool
内运行的任务的抽象基类。
A ForkJoinTask
是一个线程实体,其重量比普通线程轻得多。
大量任务和子任务可能由ForkJoinPool中的少量实际线程托管,价格为某些使用限制。
A“主” ForkJoinTask
开始执行时,明确提出到ForkJoinPool
,或者,如果不是已经从事ForkJoin计算,在开始ForkJoinPool.commonPool()
通过fork()
, invoke()
,或相关方法。 一旦开始,它通常反过来启动其他子任务。 如该类的名称所示,许多使用ForkJoinTask
程序ForkJoinTask
使用方法fork()
和join()
,或衍生物,例如invokeAll
。 然而,这个课程还提供了许多可以在高级用途中发挥作用的其他方法,以及允许支持新形式的叉/连接处理的扩展机制。
甲ForkJoinTask
是轻质形式Future
。 ForkJoinTask的ForkJoinTask
来源于一组限制(仅部分可静态执行),反映出它们主要用作计算纯函数或在纯孤立对象上运行的计算任务。 主要的协调机制是fork()
,该安排异步执行,并join()
,不继续,直到任务的结果被计算出来。 理想情况下,计算应避免使用synchronized
方法或块,并应尽可能减少其他阻止同步,除了加入其他任务,或者使用同步器,例如被广告与fork / join调度合作的Phasers。 可分割的任务也不应该执行阻塞I / O,理想情况下,访问完全独立于其他运行任务访问的变量。 这些准则是通过不允许检查异常,如松散地执行IOExceptions
抛出。 但是,计算可能仍然会遇到未经检查的异常,这些异常被转移给尝试加入它们的呼叫者。 这些例外可以另外包括RejectedExecutionException
从内部资源耗尽所产生,如未能分配内部任务队列。 Rethrown异常的行为与常规异常的方式相同,但是如果可能,包含启动计算的线程以及实际遇到异常的线程的堆栈跟踪(例如使用ex.printStackTrace()
); 最低限度只有后者。
可以定义和使用可能会阻塞的ForkJoinTasks,但是做的还需要另外三个考虑事项:(1)如果任何其他任务应该依赖于阻塞外部同步或I / O的任务,则完成很少。 事件风格的异步任务从未加入(例如,这些子类别CountedCompleter
)通常属于此类别。 (2)尽量减少资源影响,任务要小; 理想地仅执行(可能)阻塞动作。 (3)除非使用ForkJoinPool.ManagedBlocker
API,否则已知可能已阻止的任务数量小于池的ForkJoinPool.getParallelism()
级别,否则池不能保证有足够的线程可用于确保进度或性能良好。
等待完成和提取任务结果的主要方法是join()
,但有几种变体: Future.get()
方法支持可中断和/或定时等待完成,并使用Future
约定报告结果。 方法invoke()
在语义上等同于fork(); join()
但总是试图在当前线程中开始执行。 这些方法的“ 安静 ”形式不能提取结果或报告异常。 当执行一组任务时,这些可能很有用,并且您需要延迟对结果或异常的处理,直到完成。 方法invokeAll
(可用于多个版本)执行最常见的并行调用形式:分派一组任务并将其全部加入。
在最典型的用法中,fork-join对就像一个调用(fork)并从并行递归函数返回(join)。 与其他形式的递归调用一样,返回(连接)应该是最内层的。 例如, a.fork(); b.fork(); b.join(); a.join();
可能比在a
之前加入a
更b
。
任务的执行状态可以在多个细节层次查询: isDone()
如果以任何方式完成任务(包括任务被取消而不执行的情况)则为真; isCompletedNormally()
如果任务在没有取消或遇到异常的情况下完成,则为true; isCancelled()
如果任务被取消,则为真(在这种情况下getException()
返回一个CancellationException
); 如果任务被取消或遇到异常,则isCompletedAbnormally()
为真,在这种情况下, getException()
将返回遇到的异常或CancellationException
。
ForkJoinTask类通常不是直接子类。 相反,你继承了支持叉的特定风格/连接处理,通常是抽象类的一个RecursiveAction
对于不返回结果大多数计算, RecursiveTask
对于那些做了, CountedCompleter
对于那些在已完成的操作触发其它动作。 通常,具体的ForkJoinTask子类声明包含其构造函数中建立的参数的字段,然后定义compute
方法,该方法以某种方式使用此基类提供的控制方法。
方法join()
及其变体仅在完成依赖性为非循环时才适用; 也就是说,并行计算可以被描述为有向无环图(DAG)。 否则,任务可能会遇到一种形式的死锁,因为任务周期性地等待对方。 然而,该框架支持的其它方法和技术(例如使用Phaser
, helpQuiesce()
和complete(V)
),其可以使用在构建定制子类为没有静态构造为DAG的问题。 为了支持这样的用途中,ForkJoinTask可以用原子标记有short
使用值setForkJoinTaskTag(short)
或compareAndSetForkJoinTaskTag(short, short)
和使用托运getForkJoinTaskTag()
。 ForkJoinTask实现不会为了任何目的使用这些protected
方法或标签,但它们可能在构建专门的子类中有用。 例如,并行图遍历可以使用提供的方法来避免重新访问已经被处理的节点/任务。 (标记的方法名称部分笨重,以鼓励定义反映其使用模式的方法。)
大多数基础支持方法是final
,以防止覆盖本质上与底层轻量级任务调度框架相关联的实现。 开发者创建新的基本样式叉/加入处理应最低限度地实现protected
方法exec()
, setRawResult(V)
和getRawResult()
,同时还引入,可以在其子类来实现的抽象计算方法,可能依赖于其他protected
由此类提供的方法。
ForkJoinTasks应该执行相对较少的计算量。 大型任务应分为较小的子任务,通常通过递归分解。 作为一个非常粗略的经验法则,任务应该执行超过100个和少于10000个基本的计算步骤,并且应该避免不确定的循环。 如果任务太大,则并行性不能提高吞吐量。 如果太小,则内存和内部任务维护开销可能会压制处理。
这个类提供adapt
方法Runnable
和Callable
,混合执行时可能使用的ForkJoinTasks
与其他类型的任务。 当所有任务都是这种形式时,请考虑使用以asyncMode构造的池 。
ForkJoinTasks是Serializable
,它使它们可以用于扩展,如远程执行框架。 仅在执行之前或之后序列化任务是明智的,而不是执行期间。 序列化在执行本身时不依赖。
Constructor and Description |
---|
ForkJoinTask() |
Modifier and Type | Method and Description |
---|---|
static <T> ForkJoinTask<T> |
adapt(Callable<? extends T> callable)
返回一个新的
ForkJoinTask ,它执行给定的
Callable 作为其操作的
call 方法,并将其结果返回到
join() ,将遇到的任何检查的异常转换为
RuntimeException 。
|
static ForkJoinTask<?> |
adapt(Runnable runnable)
|
static <T> ForkJoinTask<T> |
adapt(Runnable runnable, T result)
|
boolean |
cancel(boolean mayInterruptIfRunning)
尝试取消执行此任务。
|
boolean |
compareAndSetForkJoinTaskTag(short e, short tag)
以原子方式有条件地设置此任务的标签值。
|
void |
complete(V value)
完成此任务,如果尚未中止或取消,返回给定的值作为后续调用的结果
join 和相关操作。
|
void |
completeExceptionally(Throwable ex)
完成此任务异常,如果尚未中止或取消,将导致给定异常
join 和相关操作。
|
protected abstract boolean |
exec()
立即执行此任务的基本操作,并返回true,如果从此方法返回后,此任务将保证已正常完成。
|
ForkJoinTask<V> |
fork()
在当前任务正在运行的池中异步执行此任务(如果适用),或使用
ForkJoinPool.commonPool() (如果不是
inForkJoinPool() )进行异步执行 。
|
V |
get()
等待计算完成,然后检索其结果。
|
V |
get(long timeout, TimeUnit unit)
如果需要等待最多在给定的时间计算完成,然后检索其结果(如果可用)。
|
Throwable |
getException()
返回由基础计算抛出的异常,或
CancellationException 取消,如果,或
null 如果没有,或者如果方法尚未完成。
|
short |
getForkJoinTaskTag()
返回此任务的标签。
|
static ForkJoinPool |
getPool()
返回托管当前任务执行的池,如果此任务在任何ForkJoinPool之外执行,则返回null。
|
static int |
getQueuedTaskCount()
返回当前工作线程已分配但尚未执行的任务数量的估计。
|
abstract V |
getRawResult()
返回由
join() 返回的结果,即使此任务异常完成,或
null 如果此任务未知已完成。
|
static int |
getSurplusQueuedTaskCount()
返回当前工作线程保留的本地排队任务数量多于可能窃取它们的其他工作线程的估计值,如果该线程未在ForkJoinPool中运行,则返回零。
|
static void |
helpQuiesce()
可能执行任务,直到托管当前任务的池
is quiescent 。
|
static boolean |
inForkJoinPool()
返回 true 如果当前线程是ForkJoinWorkerThread 执行作为ForkJoinPool计算。
|
V |
invoke()
执行此任务后,如有必要,等待其完成,并返回其结果,或者如果基础计算执行此操作,则抛出(未选中)
RuntimeException 或
Error 。
|
static <T extends ForkJoinTask<?>> |
invokeAll(Collection<T> tasks)
叉指定集合中的所有任务,当
isDone 适用于每个任务或返回(未检查)异常时返回,在这种情况下,异常被重新引导。
|
static void |
invokeAll(ForkJoinTask<?>... tasks)
叉出给定的任务,当每个任务保持isDone时
isDone ,或遇到(未检查)异常,在这种情况下,异常被重新引导。
|
static void |
invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2)
叉出给定的任务,当每个任务保持isDone时
isDone ,或者遇到(未检查)异常,在这种情况下,异常被重新引导。
|
boolean |
isCancelled()
如果此任务在正常完成之前被取消,则返回
true 。
|
boolean |
isCompletedAbnormally()
如果此任务抛出异常或被取消,返回
true 。
|
boolean |
isCompletedNormally()
如果此任务完成而不抛出异常并且未被取消,则返回
true 。
|
boolean |
isDone()
返回
true 如果任务已完成。
|
V |
join()
当
is done 返回计算结果。
|
protected static ForkJoinTask<?> |
peekNextLocalTask()
返回,但不会取消调度或执行当前线程排队但尚未执行的任务(如果可以立即可用)。
|
protected static ForkJoinTask<?> |
pollNextLocalTask()
如果当前线程正在ForkJoinPool中运行,则不执行当前线程排队的下一个任务但尚未执行的时间并返回。
|
protected static ForkJoinTask<?> |
pollTask()
如果当前线程在ForkJoinPool中运行,则不执行下一个任务,返回当前线程排队的下一个任务,但尚未执行,如果一个可用,或者如果不可用,则由其他线程分派的任务,如果可供使用的话。
|
void |
quietlyComplete()
正常完成此任务而不设置值。
|
void |
quietlyInvoke()
执行此任务并等待其完成(如有必要),而不返回其结果或抛出异常。
|
void |
quietlyJoin()
加入此任务,而不返回其结果或抛出异常。
|
void |
reinitialize()
重置此任务的内部簿记状态,允许随后的
fork 。
|
short |
setForkJoinTaskTag(short tag)
原子地设置此任务的标签值。
|
protected abstract void |
setRawResult(V value)
强制给定的值作为结果返回。
|
boolean |
tryUnfork()
尝试取消执行此任务。
|
public final ForkJoinTask<V> fork()
ForkJoinPool.commonPool()
(如果不是inForkJoinPool()
)进行异步执行 。
虽然它不一定执行,但是除非完成并重新初始化,否则任务多次分配是一种使用错误。
对此任务的状态的后续修改或其操作的任何数据不一定被除了执行它之外的任何线程一致地观察到,除非在join()
或相关方法的呼叫之前,或者呼叫isDone()
返回true
。
this
,以简化使用
public final V join()
is done
。
该方法与get()
的不同之处在于,异常完成导致RuntimeException
或Error
,而不是ExecutionException
,并且调用线程的中断不会导致该方法通过投掷InterruptedException
突然返回。
public final V invoke()
RuntimeException
或
Error
。
public static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2)
isDone
,或者遇到(未检查)异常,在这种情况下重新引发异常。
如果有多个任务遇到异常,则该方法会抛出任何一个异常。
如果任何一个任务遇到异常,另一个可能会被取消。
但是,单独任务的执行状态在特殊返回时不能得到保证。
每个任务的状态可以使用getException()
和相关方法来获取 ,以检查它们是否已被取消,正常完成或异常完成或未被处理。
t1
- 第一个任务
t2
- 第二个任务
NullPointerException
- 如果任何任务为空
public static void invokeAll(ForkJoinTask<?>... tasks)
isDone
,或遇到(未检查)异常,在这种情况下,异常被重新引导。
如果有多个任务遇到异常,则该方法会抛出任何一个异常。
如果任何一个任务遇到异常,其他任务可能被取消。
但是,单独任务的执行状态在特殊返回时不能得到保证。
每个任务的状态可以使用getException()
和相关方法来获取 ,以检查它们是否已被取消,正常完成或异常完成或未被处理。
tasks
- 任务
NullPointerException
- 如果任何任务为空
public static <T extends ForkJoinTask<?>> Collection<T> invokeAll(Collection<T> tasks)
isDone
或遇到一个(未检查)异常时返回,在这种情况下,异常被重新引导。
如果有多个任务遇到异常,则该方法会抛出任何一个异常。
如果任何一个任务遇到异常,其他任务可能被取消。
但是,单独任务的执行状态在特殊返回时不能得到保证。
每个任务的状态可以使用getException()
和相关方法来获取 ,以检查它们是否已被取消,正常完成或异常完成或未被处理。
T
- 从任务返回的值的类型
tasks
- 任务的收集
NullPointerException
- 如果任务或任何元素为空
public boolean cancel(boolean mayInterruptIfRunning)
cancel
被调用时,这个任务的执行被抑制。
经过此方法成功返回,除非有介入呼叫reinitialize()
,后续调用到isCancelled()
, isDone()
和cancel
将返回true
,并呼吁join()
,并会导致相关方法CancellationException
。
此方法可能会在子类中被覆盖,但如果是这样,仍然必须确保这些属性成立。 特别地, cancel
方法本身不能抛出异常。
该方法被设计为由其他任务调用。 要终止当前任务,您只需从其计算方法返回或抛出未经检查的异常,或者调用completeExceptionally(Throwable)
。
public final boolean isDone()
Future
复制
true
如果任务已完成。
完成可能是由于正常终止,异常或取消 - 在所有这些情况下,此方法将返回true
。
public final boolean isCancelled()
Future
复制
true
。
isCancelled
在界面
Future<V>
true
如果此任务在完成之前被取消
public final boolean isCompletedAbnormally()
true
。
true
如果此任务抛出异常或被取消
public final boolean isCompletedNormally()
true
。
true
如果此任务完成而不抛出异常并且未被取消
public final Throwable getException()
CancellationException
取消,如果,或
null
如果没有,或者如果方法尚未完成。
null
如果没有
public void completeExceptionally(Throwable ex)
join
和相关操作。
该方法可用于在异步任务中引发异常,或强制执行否则完成的任务。
不鼓励在其他情况下使用它。
这种方法是可以覆盖的,但是覆盖的版本必须调用super
实现来维护保证。
ex
- 抛出异常。
如果这个异常不是RuntimeException
或Error
,抛出的实际异常将是RuntimeException
,原因是ex
。
public void complete(V value)
join
和相关操作。
该方法可用于为异步任务提供结果,或为不能正常完成的任务提供替代处理。
不鼓励在其他情况下使用它。
这种方法是可以覆盖的,但是覆盖的版本必须调用super
实现才能保证。
value
- 此任务的结果值
public final void quietlyComplete()
setRawResult(V)
(或null
默认情况下)将返回的后续调用的结果join
及相关业务。
public final V get() throws InterruptedException, ExecutionException
get
在界面
Future<V>
CancellationException
- 如果计算被取消
ExecutionException
- 如果计算抛出异常
InterruptedException
- 如果当前线程不是ForkJoinPool的成员,并且在等待时中断
public final V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
get
在接口
Future<V>
timeout
- 等待的最长时间
unit
- 超时参数的时间单位
CancellationException
- 如果计算被取消
ExecutionException
- 如果计算抛出异常
InterruptedException
- 如果当前线程不是ForkJoinPool的成员,并且在等待时中断
TimeoutException
- 如果等待超时
public final void quietlyJoin()
public final void quietlyInvoke()
public static void helpQuiesce()
is quiescent
。
该方法可能在许多任务被分叉的设计中都可以使用,但是没有一个被明确地加入,而是在所有的处理之前执行它们。
public void reinitialize()
fork
。
这个方法允许重复使用这个任务,但是只有当这个任务从未被分支,或已经被分支,然后完成并且这个任务的所有未完成的连接也已完成时重新使用。
在任何其他使用条件下的效果不能保证。
在循环中执行子任务的预构建树时,此方法可能很有用。
完成此方法后, isDone()
报告false
和getException()
报告null
。 但是, getRawResult
返回的值不受影响。 要清除此值,可以调用setRawResult(null)
。
public static ForkJoinPool getPool()
null
如果没有
inForkJoinPool()
public static boolean inForkJoinPool()
true
如果当前线程是ForkJoinWorkerThread
执行作为ForkJoinPool计算。
true
如果当前线程是作为ForkJoinPool计算执行的ForkJoinWorkerThread
,否则false
false
public boolean tryUnfork()
true
如果
true
public static int getQueuedTaskCount()
public static int getSurplusQueuedTaskCount()
public abstract V getRawResult()
null
如果没有完成
protected abstract void setRawResult(V value)
value
- 值
protected abstract boolean exec()
true
如果此任务已知正常完成
protected static ForkJoinTask<?> peekNextLocalTask()
null
如果没有可用
protected static ForkJoinTask<?> pollNextLocalTask()
null
如果没有可用
protected static ForkJoinTask<?> pollTask()
null
结果并不一定意味着此任务正在运行的池的静止。此方法主要用于支持扩展,否则不太有用。
null
如果没有可用
public final short getForkJoinTaskTag()
public final short setForkJoinTaskTag(short tag)
tag
- 标签值
public final boolean compareAndSetForkJoinTaskTag(short e, short tag)
if (task.compareAndSetForkJoinTaskTag((short)0, (short)1))
之前检查: if (task.compareAndSetForkJoinTaskTag((short)0, (short)1))
方法,否则退出,因为节点已经被访问。
e
- 预期的标签值
tag
- 新标签值
true
如果成功;
即当前值等于e,现在是标签。
public static ForkJoinTask<?> adapt(Runnable runnable)
runnable
- 可运行的动作
public static <T> ForkJoinTask<T> adapt(Runnable runnable, T result)
T
- 结果的类型
runnable
- 可运行的动作
result
- 完成后的结果
public static <T> ForkJoinTask<T> adapt(Callable<? extends T> callable)
ForkJoinTask
,它执行给定的
Callable
作为其操作的
call
方法,并将其结果返回到
join()
,将遇到的任何检查的异常转换为
RuntimeException
。
T
- 可调用结果的类型
callable
- 可呼叫动作