一、概念
- 1.Fork/Join是jdk1.7加入的新的线程池实现
- 2.体现的是一种分治思想
- 3.适用于能够进行任务拆分的cpu密集型运算
- 4.任务拆分是将一个大型任务拆分为算法上相同的小型任务,直至不能拆分可以直接求解
- 5.与递归相关的计算,例如归并排序、斐波那契数列,都可以用分治思想进行求解
- 6.Fork/Join在分治的基础上加入了多线程,可以把每个任务的分解和合并交给不同的线程来完成,进一步提升运算效率
- 7.Fork/Join默认会创建与cpu核心数大小相同的线程池,是cpu密集型任务
二、使用
- 1.提交给Fork/Join线程池的任务需要继承RecursiveTask(有返回值)或RecursiveAction(没有返回值)
- 2.ForkJoinPool无参构造,线程数为cpu核心数
- 3.fork方法让线程池的一个线程去执行
- 4.join方法获取任务结果
三、代码示例
package com.learning.threadpool.forkjoin;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
/**
* 求1-n之间整数的和
*/
@Data
@AllArgsConstructor
@Slf4j
public class RecursiveTaskLearning extends RecursiveTask<Integer> {
private int n;
@Override
protected Integer compute() {
if(n == 1){
log.info("join() {}", n);
return n;
}
// 将任务进行拆分(fork)
RecursiveTaskLearning recursiveTaskLearning = new RecursiveTaskLearning(n - 1);
// 拆分,让线程池的一个线程去执行
recursiveTaskLearning.fork();
// 获取任务结果
int result = n + recursiveTaskLearning.join();
log.info("join() {} + {} = {}", n, recursiveTaskLearning, result);
return result;
}
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool(4);
Integer invoke = pool.invoke(new RecursiveTaskLearning(5));
System.out.println(invoke);
}
}
package com.learning.threadpool.forkjoin;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
/**
* 求1-n之间整数的和
*/
@Data
@AllArgsConstructor
@Slf4j
public class RecursiveTaskLearning_2 extends RecursiveTask<Integer> {
private int begin;
private int end;
@Override
protected Integer compute() {
if(begin == end){
log.info("join() {}", begin);
return begin;
}
if(end - begin == 1){
log.info("join() {} + {} = {}", begin, end, begin + end);
return begin + end;
}
int mid = (begin + end) / 2;
RecursiveTaskLearning_2 recursiveTaskLearning1 = new RecursiveTaskLearning_2(begin, mid);
// 拆分,让线程池的一个线程去执行
recursiveTaskLearning1.fork();
RecursiveTaskLearning_2 recursiveTaskLearning2 = new RecursiveTaskLearning_2(mid + 1, end);
// 拆分,让线程池的一个线程去执行
recursiveTaskLearning2.fork();
log.info("fork() {} + {} = ?", recursiveTaskLearning1, recursiveTaskLearning2);
// 获取任务结果
int result = recursiveTaskLearning1.join() + recursiveTaskLearning2.join();
return result;
}
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool(4);
Integer invoke = pool.invoke(new RecursiveTaskLearning_2(1, 5));
System.out.println(invoke);
}
}