- 类型参数:
V- 任务结果的类型
- 所有已实现的接口:
Serializable,Future<V>
- 已知子类:
CountedCompleter,RecursiveAction,RecursiveTask
ForkJoinPool 中运行的任务的抽象基类。 ForkJoinTask 是一个类似线程的实体,比普通线程轻得多。以一些使用限制为代价,大量任务和子任务可能由 ForkJoinPool 中的少量实际线程托管。
“主要”ForkJoinTask 在明确提交给 ForkJoinPool 时开始执行,或者,如果尚未参与 ForkJoin 计算,则通过 fork() 、invoke() 或相关方法在 ForkJoinPool.commonPool() 中开始执行。一旦启动,它通常会依次启动其他子任务。正如该类的名称所示,许多使用 ForkJoinTask 的程序仅使用方法 fork() 和 join() 或派生方法,例如 invokeAll 。但是,此类还提供了许多可以在高级用法中发挥作用的其他方法,以及允许支持新形式的 fork/join 处理的扩展机制。
ForkJoinTask 是 Future 的轻量级形式。 ForkJoinTask s 的效率源于一组限制(仅部分静态可执行),反映了它们的主要用途是作为计算任务计算纯函数或对纯孤立对象进行操作。主要协调机制是 fork() ,它安排异步执行,和 join() ,直到计算出任务的结果才继续。理想情况下,计算应该避免synchronized 方法或块,并且应该最小化其他阻塞同步,除了加入其他任务或使用同步器(例如宣传为与 fork/join 调度合作的 Phaser)。可细分任务也不应该执行阻塞 I/O,理想情况下应该访问完全独立于其他正在运行的任务访问的变量。通过不允许抛出 IOExceptions 等已检查异常来松散地执行这些准则。但是,计算仍然可能遇到未经检查的异常,这些异常会重新抛给试图加入它们的调用者。这些异常可能还包括 RejectedExecutionException 源于内部资源耗尽,例如未能分配内部任务队列。重新抛出的异常与常规异常的行为方式相同,但在可能的情况下,包含启动计算的线程以及实际遇到异常的线程的堆栈跟踪(例如使用 ex.printStackTrace() 显示);至少只有后者。
可以定义和使用可能阻塞的 ForkJoinTasks,但这样做需要进一步考虑三个因素:(1) 完成少数(如果有的话)other 任务应该依赖于阻塞外部同步或 I/O 的任务。从未加入的事件式异步任务(例如,那些子类化的 CountedCompleter )通常属于此类。 (2) 为了尽量减少对资源的影响,任务应该很小;理想情况下只执行(可能)阻塞操作。 (3) 除非使用 ForkJoinPool.ManagedBlocker API,或者已知可能阻塞的任务数少于池的 ForkJoinPool.getParallelism() 级别,否则池无法保证有足够的线程可用以确保进度或良好的性能。
等待完成和提取任务结果的主要方法是 join() ,但有几种变体: Future.get() 方法支持可中断和/或定时等待完成并使用 Future 约定报告结果。方法 invoke() 在语义上等同于 fork(); join() 但始终尝试在当前线程中开始执行。这些方法的“quiet”形式不提取结果或报告异常。当正在执行一组任务时,这些可能很有用,并且您需要延迟对结果或异常的处理,直到全部完成。方法 invokeAll(在多个版本中可用)执行最常见的并行调用形式:分叉一组任务并将它们全部加入。
在最典型的用法中,fork-join 对的作用类似于并行递归函数的调用(fork)和返回(join)。与其他形式的递归调用一样,返回(连接)应该以最内层优先的方式执行。例如,a.fork(); b.fork(); b.join(); a.join(); 可能比在 b 之前加入 a 更有效。
可以在多个详细级别查询任务的执行状态:如果任务以任何方式完成(包括任务在未执行的情况下被取消的情况),isDone() 为真; isCompletedNormally() 如果任务完成而没有取消或遇到异常则为真;如果任务被取消,则 isCancelled() 为真(在这种情况下 getException(int) 返回 CancellationException );如果任务被取消或遇到异常,则 isCompletedAbnormally() 为真,在这种情况下,getException(int) 将返回遇到的异常或 CancellationException 。
ForkJoinTask 类通常不直接子类化。相反,您将支持特定派生/合并处理风格的抽象类之一子类化,通常 RecursiveAction 用于大多数不返回结果的计算,RecursiveTask 用于返回结果的计算,CountedCompleter 用于完成的操作触发其他操作的计算。通常,具体的 ForkJoinTask 子类声明包含其参数的字段,在构造函数中建立,然后定义一个 compute 方法,该方法以某种方式使用此基类提供的控制方法。
方法 join() 及其变体仅适用于完成依赖性是非循环的;也就是说,并行计算可以描述为有向无环图(DAG)。否则,执行可能会遇到某种形式的死锁,因为任务会循环等待彼此。但是,此框架支持其他方法和技术(例如使用 Phaser 、 helpQuiesce() 和 complete(V) ),这些方法和技术可用于为非静态结构化为 DAG 的问题构建自定义子类。为了支持这种用法,ForkJoinTask 可以使用setForkJoinTaskTag(short) 或compareAndSetForkJoinTaskTag(short, short) 原子地tagged 和short 值并使用getForkJoinTaskTag() 检查。 ForkJoinTask 实现不出于任何目的使用这些 protected 方法或标记,但它们可能用于构建专门的子类。例如,并行图遍历可以使用提供的方法来避免重新访问已经处理过的节点/任务。 (用于标记的方法名称很庞大,部分原因是为了鼓励定义反映其使用模式的方法。)
大多数基本支持方法是 final ,以防止覆盖本质上与底层轻量级任务调度框架相关的实现。创建新的 fork/join 处理基本样式的开发人员应至少实现 protected 方法 exec() 、setRawResult(V) 和 getRawResult() ,同时还引入可以在其子类中实现的抽象计算方法,可能依赖此类提供的其他 protected 方法。
ForkJoinTasks 应该执行相对少量的计算。大任务应该被拆分成更小的子任务,通常通过递归分解。作为一个非常粗略的经验法则,一个任务应该执行多于 100 且少于 10000 的基本计算步骤,并且应该避免无限循环。如果任务太大,那么并行就无法提高吞吐量。如果太小,则内存和内部任务维护开销可能会使处理不堪重负。
此类为 Runnable 和 Callable 提供了 adapt 方法,在将 ForkJoinTasks 与其他类型的任务混合执行时可能会有用。当所有任务都是这种形式时,请考虑使用在 asyncMode 中构建的池。
ForkJoinTasks 是 Serializable ,这使它们能够用于远程执行框架等扩展。只在执行之前或之后而不是在执行期间序列化任务是明智的。在执行本身期间不依赖于序列化。
- 自从:
- 1.7
- 参见:
-
内部类总结
在接口 java.util.concurrent.Future 中声明的嵌套类/接口
Future.State -
构造方法总结
构造方法 -
方法总结
修饰符和类型方法描述static ForkJoinTask<?>static <T> ForkJoinTask<T>static <T> ForkJoinTask<T>static <T> ForkJoinTask<T>adaptInterruptible(Callable<? extends T> callable) booleancancel(boolean mayInterruptIfRunning) 尝试取消执行此任务。final booleancompareAndSetForkJoinTaskTag(short expect, short update) 以原子方式有条件地为此任务设置标签值。void完成此任务,如果尚未中止或取消,则返回给定值作为后续调用join和相关操作的结果。void异常完成此任务,如果尚未中止或取消,则导致它在join和相关操作上抛出给定的异常。protected abstract booleanexec()立即执行此任务的基本操作并返回 true,如果从此方法返回时,此任务已保证已完成。final ForkJoinTask<V>fork()安排在当前任务正在运行的池中异步执行此任务(如果适用),或者使用ForkJoinPool.commonPool()(如果不是inForkJoinPool())。final Vget()如有必要,等待计算完成,然后检索其结果。final V如有必要,最多等待计算完成的给定时间,然后检索其结果(如果可用)。final Throwable返回基础计算抛出的异常,如果取消则返回CancellationException,如果没有或方法尚未完成则返回null。final short返回此任务的标签。static ForkJoinPoolgetPool()返回托管当前线程的池,如果当前线程在任何 ForkJoinPool 之外执行,则返回null。static int返回当前工作线程已分叉但尚未执行的任务数的估计值。abstract V返回将由join()返回的结果,即使此任务异常完成,或null如果不知道此任务已完成。static int返回当前工作线程持有的本地排队任务比可能窃取它们的其他工作线程多多少的估计值,如果该线程未在 ForkJoinPool 中运行,则返回零。static void可能会执行任务,直到托管当前任务的池 是静止的 为止。static boolean如果当前线程是作为 ForkJoinPool 计算执行的ForkJoinWorkerThread,则返回true。final Vinvoke()开始执行此任务,如有必要等待其完成,并返回其结果,或抛出(未检查的)RuntimeException或Error(如果底层计算这样做)。static <T extends ForkJoinTask<?>>
Collection<T>invokeAll(Collection<T> tasks) 分叉指定集合中的所有任务,当isDone为每个任务保留或遇到(未经检查的)异常时返回,在这种情况下会重新抛出异常。static voidinvokeAll(ForkJoinTask<?>... tasks) 分叉给定的任务,当isDone保留每个任务或遇到(未经检查的)异常时返回,在这种情况下会重新抛出异常。static voidinvokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2) 分叉给定的任务,当isDone保留每个任务或遇到(未经检查的)异常时返回,在这种情况下会重新抛出异常。final boolean如果此任务在正常完成之前被取消,则返回true。final boolean如果此任务抛出异常或被取消,则返回true。final boolean如果此任务完成且未引发异常且未被取消,则返回true。final booleanisDone()如果此任务完成,则返回true。final Vjoin()已经完成了 时返回计算结果。protected static ForkJoinTask<?>返回但不取消计划或执行当前线程排队但尚未执行的任务(如果有任务立即可用)。protected static ForkJoinTask<?>如果当前线程正在 ForkJoinPool 中运行,则取消调度并返回(不执行)当前线程排队但尚未执行的下一个任务。protected static ForkJoinTask<?>如果当前线程在 ForkJoinPool 中运行,则取消调度并返回(如果有的话)从外部提交到池中的任务,而不执行。protected static ForkJoinTask<?>pollTask()如果当前线程在 ForkJoinPool 中运行,取消调度并返回,而不执行,当前线程排队但尚未执行的下一个任务,如果可用,或者如果不可用,则由其他线程分叉的任务,如果可供使用的话。final void在不设置值的情况下正常完成此任务。final void开始执行此任务并在必要时等待其完成,而不返回其结果或抛出其异常。final void加入这个任务,不返回它的结果或抛出它的异常。final booleanquietlyJoin(long timeout, TimeUnit unit) 尝试加入此任务,如果它在给定超时之前完成(可能是异常情况)并且当前线程未被中断,则返回 true。final booleanquietlyJoinUninterruptibly(long timeout, TimeUnit unit) 尝试加入此任务,如果它在给定超时之前完成(可能异常),则返回 true。void重置此任务的内部簿记状态,允许后续的fork。final shortsetForkJoinTaskTag(short newValue) 以原子方式为此任务设置标记值并返回旧值。protected abstract voidsetRawResult(V value) 强制将给定值作为结果返回。boolean尝试取消计划执行此任务。在类 java.lang.Object 中声明的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait在接口 java.util.concurrent.Future 中声明的方法
exceptionNow, resultNow, state
-
构造方法详细信息
-
ForkJoinTask
public ForkJoinTask()子类调用的构造方法。
-
-
方法详情
-
fork
安排在当前任务正在运行的池中异步执行此任务(如果适用),或者使用ForkJoinPool.commonPool()(如果不是inForkJoinPool())。虽然不一定强制执行,但多次分叉任务是一个使用错误,除非它已完成并重新初始化。除非在调用join()或相关方法之前调用join()或相关方法,或者调用isDone()返回true,否则对该任务的状态或其操作的任何数据的后续修改不一定能被执行它的线程以外的任何线程一致地观察到。- 返回:
this,以简化使用
-
join
已经完成了 时返回计算结果。此方法与get()的不同之处在于,异常完成会导致RuntimeException或Error而不是ExecutionException,并且调用线程的中断会 not 导致该方法通过抛出InterruptedException突然返回。- 返回:
- 计算结果
-
invoke
开始执行此任务,如有必要等待其完成,并返回其结果,或抛出(未检查的)RuntimeException或Error(如果底层计算这样做)。- 返回:
- 计算结果
-
invokeAll
分叉给定的任务,当isDone保留每个任务或遇到(未经检查的)异常时返回,在这种情况下会重新抛出异常。如果多个任务遇到异常,则此方法将抛出这些异常中的任何一个。如果任何一个任务遇到异常,另一个任务可能会被取消。但是,异常返回时不保证单个任务的执行状态。每个任务的状态可以使用getException()和相关方法来检查它们是否已被取消、正常或异常完成或未处理。- 参数:
t1- 第一个任务t2- 第二个任务- 抛出:
NullPointerException- 如果任何任务为空
-
invokeAll
分叉给定的任务,当isDone保留每个任务或遇到(未经检查的)异常时返回,在这种情况下会重新抛出异常。如果多个任务遇到异常,则此方法将抛出这些异常中的任何一个。如果任何任务遇到异常,其他任务可能会被取消。但是,异常返回时不保证单个任务的执行状态。每个任务的状态可以使用getException()和相关方法来检查它们是否已被取消、正常或异常完成或未处理。- 参数:
tasks- 任务- 抛出:
NullPointerException- 如果任何任务为空
-
invokeAll
分叉指定集合中的所有任务,当isDone为每个任务保留或遇到(未经检查的)异常时返回,在这种情况下会重新抛出异常。如果多个任务遇到异常,则此方法将抛出这些异常中的任何一个。如果任何任务遇到异常,其他任务可能会被取消。但是,异常返回时不保证单个任务的执行状态。每个任务的状态可以使用getException()和相关方法来检查它们是否已被取消、正常或异常完成或未处理。- 类型参数:
T- 从任务返回的值的类型- 参数:
tasks- 任务集合- 返回:
- tasks 参数,以简化使用
- 抛出:
NullPointerException- 如果任务或任何元素为空
-
cancel
public boolean cancel(boolean mayInterruptIfRunning) 尝试取消执行此任务。如果任务已经完成或由于其他原因无法取消,则此尝试将失败。如果成功,并且在调用cancel时此任务尚未启动,则会抑制此任务的执行。此方法成功返回后,除非有对reinitialize()的干预调用,否则对isCancelled()、isDone()和cancel的后续调用将返回true,对join()和相关方法的调用将返回CancellationException。此方法可能会在子类中被覆盖,但如果是这样,仍必须确保这些属性成立。特别是,
cancel方法本身不能抛出异常。此方法旨在由 other 任务调用。要终止当前任务,您可以从其计算方法返回或抛出未经检查的异常,或调用
completeExceptionally(Throwable)。 -
isDone
public final boolean isDone()从接口Future复制的描述如果此任务完成,则返回true。完成可能是由于正常终止、异常或取消——在所有这些情况下,此方法将返回true。 -
isCancelled
public final boolean isCancelled()从接口Future复制的描述如果此任务在正常完成之前被取消,则返回true。- 指定者:
isCancelled在接口Future<V>中- 返回:
true如果此任务在完成之前被取消
-
isCompletedAbnormally
public final boolean isCompletedAbnormally()如果此任务抛出异常或被取消,则返回true。- 返回:
true如果此任务抛出异常或被取消
-
isCompletedNormally
public final boolean isCompletedNormally()如果此任务完成且未引发异常且未被取消,则返回true。- 返回:
true如果此任务完成且未抛出异常且未被取消
-
getException
返回基础计算抛出的异常,如果取消则返回CancellationException,如果没有或方法尚未完成则返回null。- 返回:
-
异常,如果没有则为
null
-
completeExceptionally
异常完成此任务,如果尚未中止或取消,则导致它在join和相关操作上抛出给定的异常。此方法可用于在异步任务中引发异常,或强制完成原本不会完成的任务。不鼓励在其他情况下使用它。此方法是可重写的,但重写版本必须调用super实现以维护保证。- 参数:
ex- 抛出的异常。如果此异常不是RuntimeException或Error,则抛出的实际异常将是RuntimeException,原因为ex。
-
complete
完成此任务,如果尚未中止或取消,则返回给定值作为后续调用join和相关操作的结果。此方法可用于为异步任务提供结果,或为无法正常完成的任务提供替代处理。不鼓励在其他情况下使用它。此方法是可重写的,但重写版本必须调用super实现以维护保证。- 参数:
value- 此任务的结果值
-
quietlyComplete
public final void quietlyComplete()- 自从:
- 1.8
-
get
如有必要,等待计算完成,然后检索其结果。- 指定者:
get在接口Future<V>中- 返回:
- 计算结果
- 抛出:
CancellationException- 如果计算被取消ExecutionException- 如果计算抛出异常InterruptedException- 如果当前线程不是 ForkJoinPool 的成员并且在等待时被中断
-
get
public final V get(long timeout, TimeUnit unit) throws InterruptedException , ExecutionException , TimeoutException 如有必要,最多等待计算完成的给定时间,然后检索其结果(如果可用)。- 指定者:
get在接口Future<V>中- 参数:
timeout- 最长时间等待unit- 超时参数的时间单位- 返回:
- 计算结果
- 抛出:
CancellationException- 如果计算被取消ExecutionException- 如果计算抛出异常InterruptedException- 如果当前线程不是 ForkJoinPool 的成员并且在等待时被中断TimeoutException- 如果等待超时
-
quietlyJoin
public final void quietlyJoin()加入这个任务,不返回它的结果或抛出它的异常。当某些任务已被取消或已知已中止时,此方法在处理任务集合时可能很有用。 -
quietlyInvoke
public final void quietlyInvoke()开始执行此任务并在必要时等待其完成,而不返回其结果或抛出其异常。 -
quietlyJoin
尝试加入此任务,如果它在给定超时之前完成(可能是异常情况)并且当前线程未被中断,则返回 true。- 参数:
timeout- 最长时间等待unit- 超时参数的时间单位- 返回:
- 如果此任务完成,则为真
- 抛出:
InterruptedException- 如果当前线程在等待时被中断- 自从:
- 19
-
quietlyJoinUninterruptibly
尝试加入此任务,如果它在给定超时之前完成(可能异常),则返回 true。- 参数:
timeout- 最长时间等待unit- 超时参数的时间单位- 返回:
- 如果此任务完成,则为真
- 自从:
- 19
-
helpQuiesce
public static void helpQuiesce()可能会执行任务,直到托管当前任务的池 是静止的 为止。此方法可用于许多任务被分叉但没有明确加入的设计,而是执行它们直到所有任务都被处理。 -
reinitialize
public void reinitialize()重置此任务的内部簿记状态,允许后续的fork。此方法允许重复重用此任务,但前提是此任务从未被分叉或已经分叉,然后完成并且此任务的所有未完成的连接也已完成时才发生重用。不保证任何其他使用条件下的效果。在循环中执行预先构建的子任务树时,此方法可能很有用。完成此方法后,
isDone()报告false,getException()报告null。但是,getRawResult返回的值不受影响。要清除此值,您可以调用setRawResult(null)。 -
getPool
返回托管当前线程的池,如果当前线程在任何 ForkJoinPool 之外执行,则返回null。当且仅当
inForkJoinPool()返回false时,此方法返回null。- 返回:
-
池,或者
null如果没有
-
inForkJoinPool
public static boolean inForkJoinPool()如果当前线程是作为 ForkJoinPool 计算执行的ForkJoinWorkerThread,则返回true。- 返回:
true如果当前线程是作为 ForkJoinPool 计算执行的ForkJoinWorkerThread,否则为false
-
tryUnfork
public boolean tryUnfork()尝试取消计划执行此任务。如果此任务是当前线程最近分叉的任务,并且尚未在另一个线程中开始执行,则此方法通常(但不保证)成功。当安排替代本地处理可能已经但没有被盗的任务时,此方法可能很有用。- 返回:
true如果未分叉
-
getQueuedTaskCount
public static int getQueuedTaskCount()返回当前工作线程已分叉但尚未执行的任务数的估计值。该值对于是否分叉其他任务的启发式决策可能很有用。- 返回:
- 任务数
-
getSurplusQueuedTaskCount
public static int getSurplusQueuedTaskCount()返回当前工作线程持有的本地排队任务比可能窃取它们的其他工作线程多多少的估计值,如果该线程未在 ForkJoinPool 中运行,则返回零。该值对于是否分叉其他任务的启发式决策可能很有用。在 ForkJoinTasks 的许多用法中,在稳定状态下,每个 worker 应该致力于保持少量恒定的任务盈余(例如 3),并且如果超过此阈值则在本地处理计算。- 返回:
- 剩余任务数,可能为负数
-
getRawResult
返回将由join()返回的结果,即使此任务异常完成,或null如果不知道此任务已完成。此方法旨在帮助调试以及支持扩展。不鼓励在任何其他上下文中使用它。- 返回:
-
结果,或者
null如果没有完成
-
setRawResult
强制将给定值作为结果返回。此方法旨在支持扩展,通常不应以其他方式调用。- 参数:
value- 值
-
exec
protected abstract boolean exec()立即执行此任务的基本操作并返回 true,如果从此方法返回时,此任务已保证已完成。否则此方法可能会返回 false,以指示此任务不一定完成(或不知道是否已完成),例如在需要显式调用完成方法的异步操作中。此方法也可能会抛出一个(未经检查的)异常以指示异常退出。此方法旨在支持扩展,通常不应以其他方式调用。- 返回:
true如果已知此任务已正常完成
-
peekNextLocalTask
返回但不取消计划或执行当前线程排队但尚未执行的任务(如果有任务立即可用)。无法保证此任务接下来会实际轮询或执行。相反,即使任务存在但如果不与其他线程争用就无法访问,此方法也可能返回 null。此方法主要用于支持扩展,否则不太可能有用。- 返回:
-
下一个任务,或者
null如果没有可用的
-
pollNextLocalTask
如果当前线程正在 ForkJoinPool 中运行,则取消调度并返回(不执行)当前线程排队但尚未执行的下一个任务。此方法主要用于支持扩展,否则不太可能有用。- 返回:
-
下一个任务,或者
null如果没有可用的
-
pollTask
如果当前线程在 ForkJoinPool 中运行,取消调度并返回,而不执行,当前线程排队但尚未执行的下一个任务,如果可用,或者如果不可用,则由其他线程分叉的任务,如果可供使用的话。可用性可能是暂时的,因此null结果并不一定意味着该任务正在其中运行的池处于静止状态。此方法主要用于支持扩展,否则不太可能有用。- 返回:
-
一个任务,或者
null如果没有可用的
-
pollSubmission
如果当前线程在 ForkJoinPool 中运行,则取消调度并返回(如果有的话)从外部提交到池中的任务,而不执行。可用性可能是暂时的,因此null结果并不一定意味着池处于静止状态。此方法主要用于支持扩展,否则不太可能有用。- 返回:
-
一个任务,或者
null如果没有可用的 - 自从:
- 9
-
getForkJoinTaskTag
public final short getForkJoinTaskTag()返回此任务的标签。- 返回:
- 这个任务的标签
- 自从:
- 1.8
-
setForkJoinTaskTag
public final short setForkJoinTaskTag(short newValue) 以原子方式为此任务设置标记值并返回旧值。- 参数:
newValue- 新标签值- 返回:
- 标签的先前值
- 自从:
- 1.8
-
compareAndSetForkJoinTaskTag
public final boolean compareAndSetForkJoinTaskTag(short expect, short update) 以原子方式有条件地为此任务设置标签值。在其他应用程序中,标签可以用作在图上运行的任务中的访问标记,如在检查方法中:if (task.compareAndSetForkJoinTaskTag((short)0, (short)1))在处理之前,否则退出,因为该节点已经被访问过。- 参数:
expect- 预期的标签值update- 新标签值- 返回:
true如果成功;即,当前值等于expect并更改为update。- 自从:
- 1.8
-
adapt
- 参数:
runnable- 可运行的动作- 返回:
- 任务
-
adapt
- 类型参数:
T- 结果的类型- 参数:
runnable- 可运行的动作result- 完成后的结果- 返回:
- 任务
-
adapt
- 类型参数:
T- 可调用结果的类型- 参数:
callable- 可调用操作- 返回:
- 任务
-
adaptInterruptible
返回一个新的ForkJoinTask执行给定Callable的call方法作为其操作,并在join()上返回其结果,将遇到的任何检查异常转换为RuntimeException。此外,使用mayInterruptIfRunning true调用cancel将尝试中断执行任务的线程。- 类型参数:
T- 可调用结果的类型- 参数:
callable- 可调用操作- 返回:
- 任务
- 自从:
- 19
-