ForkJoin简介
- 简化了多线程的创建和使用
- 自动使用多处理器,将任务分解成,各自在自己的CPU上运行
传统多线程编程
多线程编程主要利用空闲时间,在单核CPU系统中,多线程允许两个或多个任务共享CPU。
Java Fork/Join 框架
import java.util.concurrent.*;
核心类
-
ForkJoinTask<V>
: 定义任务的抽象类 -
ForkJoinPool
: 管理ForkJoinTask
的执行 -
RecursiveAction
:ForkJoinTask
的子类,用于不返回值的任务 -
RecursiveTask<V>
:ForkJoinTask
的子类,用于返回值的任务
核心类说明
-
ForkJoinTask<V>
V
指定了任务的结果类型,ForkJoinTask
通过线程来执行,本身不是执行线程。-
final ForkJoinTask<V> fork()
为调用任务的异步执行提交调用任务,即调用
fork()
方法的线程将持续运行。在调度好任务的执行后返回this
;如果没有在ForkJoinPool
中执行时调用fork()
方法,则会自动使用一个公共池。 -
final V join()
等待调用该方法的任务中止,任务结果被返回。
-
final V invoke()
将并行和连接操作合并到单个调用中,开始一个任务并等待该任务结束。
static void invokeAll(ForkJoinTask<?> taskA, ForkJoinTask<?> taskB)
-
static void invokeAll(ForkJoinTask<?> ... taskList)
同时调用多个任务,会等待
-
boolean cancel(boolean interruptOK)
任务被取消就返回
true
,已经结束或者不能取消返回false
。一般用来在任务代码外部调用。 -
final boolean isCancelled()
如果调用任务在结束之前已经取消,返回
true
, 否则返回false
. -
final boolean isCompletedNormally()
正常结束,没有抛出异常且没有通过调用
cancel()
方法来取消,返回true
。 final boolean isCompletedAbnormally()
-
void reinitialize()
正常情况,任务一旦完成就不可以重新启动。调用此方法初始化任务的状态,使其可以再次运行。但是不会影响任务的结果。
-
-
RecursiveAction
用于为不返回结果的任务实现递归的、分而治之的策略
-
protected abstract void compute()
定义具体任务
-
-
RecursiveTask<V>
用于为返回结果的任务实现递归的、分而治之的策略
-
protected abstract V compute()
定义具体任务
- 必须累加结果
- 一般通过显式调用
fork()
和join()
开始子任务
-
-
ForkJoinPool
ForkJoinTask
的执行发生在ForkJoinPool
中,该类管理任务的执行。第一个任务通常被认为是主任务,也通常由主任务开始其他的由池管理的子任务。开始主任务
<T> T invoke(ForkJoinTask<T> task)
等待任务返回结果void execute(ForkJoinTask<?> task)
不等待任务返回void execute(Runnable task)
创建对象
-
使用构造函数获取
-
ForkJoinPool()
支持的并行级别等于系统中可用处理器的数量
-
ForkJoinPool(int pLevel)
pLevel > 0
且不可超过实现的限制
-
-
使用公共池(静态对象)
static ForkJoinPool commonPool()
返回公共池的引用,提供了默认的并行级别。
- 没有显式创建池,会自动使用公共池。
- 在计算环境外,对任务调用
fork() 、invoke()
方法,将自动使用公共池启动任务。
其他方法
-
int getParallelism()
获取并行级别 int getCommonPoolParallelism()
-
int avaliableProcessors()
获取系统中可用处理器的数量,类Runtime定义的
线程管理
ForkJoinPool
使用一种称为工作挪用(daemon thread)的方式管理线程的执行。
- 每个worker线程维护一个任务队列。如果某个worker线程的任务队列为空,该worker线程将从其他worker线程取得任务。提高效率,维持负载均衡。
- 使用守护线程。当所有线程都中止时,守护线程自动终止。因此不需要显示关闭
ForkJoinPool
。可以通过shutdown()
关闭。但是对公共池不起作用。