原理:
定义:一个并行计算框架
用途:解决分治算法中的大规模任务。Fork/Join框架是基于工作窃取算法(work-stealing)的。
Fork/Join框架的核心概念有两个:
1.Fork(分割):将一个大任务,划分成多个相互独立且较小的子任务,这些子任务可以并行的执行。当一个任务被分割成多个子任务后,他们会进入到线程池的等待队列中等待执行。
2.Join(合并):等待子任务的执行结果,并将子任务的结果合并成一个整体结果。通常,在等待子任务时,线程会暂时挂起,执行其他可用的任务。
主要类:
ForkJoinPool,RecusiveTask(用于有返回值的任务),RecusiveAction(用于无返回值的任务)。
ForkJoinPool类的方法:
ForkJoinPool(int parallelism)
:构造一个指定并行度(即线程数)的ForkJoinPool
对象。submit(ForkJoinTask<T> task)
:提交一个 Fork/Join 任务给线程池进行执行,并返回一个ForkJoinTask
对象,可用于获取任务的执行结果或取消任务。execute(ForkJoinTask<?> task)
:以异步无返回值的方式执行一个 Fork/Join 任务。invoke(ForkJoinTask<T> task)
:同步地执行一个 Fork/Join 任务,并返回任务的结果。awaitTermination(long timeout, TimeUnit unit)
:阻塞当前线程,直到所有提交的任务执行完毕或超时。shutdown()
:平缓地关闭线程池,等待已提交的任务完成执行。shutdownNow()
:立即关闭线程池,尝试中断正在执行的任务并返回未执行的任务列表。getParallelism()
:获取当前线程池的并行度(即线程数)。getPoolSize()
:获取当前线程池中正在活动的线程数。getActiveThreadCount()
:获取当前线程池中正在执行任务的线程数。getQueuedTaskCount()
:获取当前线程池等待执行的任务数。getStealCount()
:获取当前线程池中发生的工作窃取次数。
这些方法只是 ForkJoinPool
类中的一部分,它还提供了其他一些方法用于管理和监控 Fork/Join 任务的执行。通过使用这些方法,可以更好地控制和优化 Fork/Join 任务的并行执行效果。
示例:
package com.springBatch.demo.forkjoinDemo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.concurrent.RecursiveTask;
@EqualsAndHashCode(callSuper = true)
@Data
public class FibonacciTask extends RecursiveTask<Integer> {
//3.定义执行任务的阈值
private final int n;
//2.重写比较方法
@Override
protected Integer compute() {
//4.
if (n <= 1) {
return n;
} else {
FibonacciTask f1 = new FibonacciTask(n - 1);
f1.fork();
FibonacciTask f2 = new FibonacciTask(n - 2);
return f2.compute()+f1.join();
}
}
}
package com.springBatch.demo.forkjoinDemo;
import java.util.concurrent.ForkJoinPool;
public class Demo {
public static void main(String[] args) {
int n=10;
ForkJoinPool forkJoinPool = new ForkJoinPool();
FibonacciTask fibonacciTask = new FibonacciTask(n);
Integer result = forkJoinPool.invoke(fibonacciTask);
System.out.println("第"+n+"个斐波那契数列是:"+result);
}
}
附录:
- 分治算法:
- 将一个大的问题,划分成许多小的子问题,然后递归的解决这些问题,最后将这些子问题的解,合并起来,得到最终的结果。
- 分治算法包含以下步骤:
- 分解(Divide):将原来的任务,分解成若干个规模更小且相互独立的子问题。
- 解决(Conquer):递归的解决每个子问题。如果子问题,足够小,无需进一步划分,直接求解。
- 合并(Combine):将各个子问题的解合并起来,得到原始问题的解。
- 递归:
- 定义:一种算法或者函数的实现方式,通过调用自身来解决问题。函数在执行过程中,需要解决一个相同但规模更小的子问题时,他会再次调用自身,并将子问题作为参数,传递给自己。
- 递归通常包含两个部分:
- 递归基(Base case):也称终止条件。当满足某些条件时,递归就不再继续,即不再进行递归调用自身,而是返回一个确定的值,终止递归过程。
- 递归步骤(Recursive step):递归本质上是将原始问题划分成多个相似的子问题,并将这些问题,用相同的过程解决,每次递归调用会处理规模更小的子问题,直到达到递归终止条件为止。