**1. Fork-Join 框架应用场景**
Java SE7 引入的 Fork-Join 框架专门用来处理一些应用程序可能对每个处理器内核分别使用一个线程,来完成计算密集型任务,如图像或视频处理。
<br/>
**2. Fork-Join框架使用步骤**
```
// 创建一个继承了RecursiveTask<T>抽象类的对象
// 重写RecursiveTask<T>抽象类的compute方法,任务代码就放在compute方法中,该方法不允许调用
// 在compute方法内部调用invokeAll(first, second)方法接收任务。
Counter counter = new Counter(numbers, 0, numbers.length, x -> x > 0.5);
// 创建Fork-Join框架
ForkJoinPool pool = new ForkJoinPool();
// 将任务提交到Fork-Join框架中,并执行
pool.invoke(counter);
// 可以调用join方法获取compute方法的计算结果
// 注意:get方法也可以获取compute方法的计算结果,但是会抛出已检查异常,
// 而compute方法不允许抛出这些异常,所以不太常用。
System.out.println(counter.join());
```
案例演示:根据条件将一个数组一分为二,分别统计这两部分,最后将结果相加。
```java
/**
* 该程序演示了fork-join框架
*
* @author Cay Horstmann
* @version 1.01 2015-06-21
*/
public class ForkJoinTest {
public static void main(String[] args) {
final int SIZE = 10000000;
double[] numbers = new double[SIZE];
for (int i = 0; i < SIZE; i++) numbers[i] = Math.random();
Counter counter = new Counter(numbers, 0, numbers.length, x -> x > 0.5);
//创建Fork-Join框架
ForkJoinPool pool = new ForkJoinPool();
//将任务提交到Fork-Join框架中
pool.invoke(counter);
//join方法可以获得compute方法的计算结果
System.out.println(counter.join());
}
}
class Counter extends RecursiveTask<Integer> {
public static final int THRESHOLD = 1000;
private double[] values;
private int from;
private int to;
private DoublePredicate filter;
public Counter(double[] values, int from, int to, DoublePredicate filter) {
this.values = values;
this.from = from;
this.to = to;
this.filter = filter;
}
@Override
protected Integer compute() {
if (to - from < THRESHOLD) {
int count = 0;
for (int i = from; i < to; i++) {
//test方法为判断输入的参数与给定的参数比较是否满足要求,
//是则返回true。这里的要求是值大于0.5则满足条件
if (filter.test(values[i])) count++;
}
return count;
} else {
int mid = (from + to) / 2;
Counter first = new Counter(values, from, mid, filter);
Counter second = new Counter(values, mid, to, filter);
//接收任务并阻塞,直到这些任务完成
invokeAll(first, second);
//对每个子任务的结果进行总结,join方法可以获得compute方法的计算结果
return first.join() + second.join();
}
}
}
```
- 网络通信
- 网络协议
- 端口和套接字
- TCP网络程序
- UDP网络程序
- 多线程聊天室
- 多线程
- 线程相关概念
- 线程实现方式
- 中断线程
- 线程生命周期
- 线程优先级
- 优先级规则
- 案例演示
- 线程同步机制
- 线程同步机制
- synchronized关键字
- ReentrantLock类
- Condition类
- 监视器概念
- volatile关键字
- final变量
- 死锁
- 线程局部变量
- 读/写锁
- 原子类
- 阻塞队列
- 工作规则
- 案例演示
- 常用阻塞队列
- 线程安全集合
- 高效的映射/集/队列
- 并发集视图
- 写数组的拷贝
- Arrays类的并行数组算法
- 同步包装器
- Callable与Future
- 执行器
- 线程池
- 预定执行
- 控制任务组
- Fork-Join框架
- 同步器
- 同步器
- 信号量
- CountDownLatch类
- CyclicBarrier类
- Exchanger类
- SynchronousQueue类
- 线程与Swing
- Swing与线程问题
- 两个原则
- Swing工作线程
- 单一线程规则
- 文件IO
- File类
- 文件输入输出
- ZIP压缩文件
- 集合
- 集合框架
- 集合接口
- 集合实现类
- 线程安全集合
- 集合算法
- 迭代器
- 集合排序
- JDBC
- JDBC是什么
- JDBC-ODBC桥
- JDBC驱动程序类型
- JDBC常用类与接口
- 数据库操作
- 连接数据库
- 增/删/改/查/预处理
- 事务
- 批处理
- commons-dbutils工具
- 安全问题
- Jedis
- 使用Jedis操作Redis数据库
- JSON转换
- 使用连接池
- 案例
- 单例破坏
- 单例定义
- 单例实现方式
- 懒汉式实现单例
- 饿汉式实现单例
- 单例破坏
- 类的单例破坏
- 枚举的单例破坏
- 克隆
- 克隆是什么
- 浅克隆
- 深克隆
- 注解
- 注解是什么
- 三大注解
- 内置注解
- 元注解
- 自定义注解
- NIO
- 相关概念
- BIO/NIO/AIO
- 多线程编程
- 线程同步
- 线程通信
- NIO
- NIO三大核心组件
- NIO网络编程
- NIO文件读写
- AIO
- Java8新特性
- Lambda表达式
- 方法引用
- 函数式接口
- 默认方法
- 什么是默认方法
- 默认方法语法格式
- 多个同名的默认方法问题
- 静态默认方法
- 默认方法实例
- Stream
- Stream是什么
- Stream示例
- Optional容器
- 新的日期时间API
- Base64
- SPI
- SPI是什么
- SPI与API的区别
- 常见场景
- 使用SPI需遵循的约定
- SPI使用步骤