java拾遗
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()开始子任务
-
-
ForkJoinPoolForkJoinTask的执行发生在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()关闭。但是对公共池不起作用。