Fork/Join框架 demo
demo1: 使⽤Fork/Join来求,斐波那契数列第n项
斐波那契数列数列是⼀个线性递推数列,从第三项开始,每⼀项的值都等于
前两项之和:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89······
如果设f(n)为该数列的第n项(n∈N*),那么有:f(n) = f(n-1) + f(n-2)。
import org.junit.Test;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;
/**
* Created by DELL on 2020/7/20.
*/
public class FibonacciTest {
class Fibonacci extends RecursiveTask<Integer> {
int n;
public Fibonacci(int n) {
this.n = n;
}
// 主要的实现逻辑都在compute()⾥
@Override
protected Integer compute() {
// 这⾥先假设 n >= 0
if (n <= 1) {
return n;
} else {
// f(n-1)
Fibonacci f1 = new Fibonacci(n - 1);
f1.fork();
// f(n-2)
Fibonacci f2 = new Fibonacci(n - 2);
f2.fork();
// f(n) = f(n-1) + f(n-2)
return f1.join() + f2.join();
}
}
}
@Test
public void testFib() throws ExecutionException, InterruptedException {
ForkJoinPool forkJoinPool = new ForkJoinPool();
System.out.println("CPU核数:" + Runtime.getRuntime().availableProcessors());
long start = System.currentTimeMillis();
Fibonacci fibonacci = new Fibonacci(40);
Future<Integer> future = forkJoinPool.submit(fibonacci);
System.out.println(future.get());
long end = System.currentTimeMillis();
System.out.println(String.format("耗时:%d millis", end - start));
}
}
输出:
1 2 3 | CPU核数: 4 计算结果: 102334155 耗时: 9490 millis |
demo2:求1+2+3+4的结果
Fork/Join框架分割任务,将每个子任务最多执行两个数的相加,那么我们设置分割的阈值是2,由于是4个数字相加,所以Fork/Join框架会把这个任务fork成两个子任务,子任务一负责计算1+2,子任务二负责计算3+4,然后再join两个子任务的结果。因为是有结果的任务,所以必须继承RecursiveTask
import java.util.concurrent.ExecutionException; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.Future; import java.util.concurrent.RecursiveTask; /** * * @author aikq * @date 2018年11月21日 20:37 */ public class ForkJoinTaskDemo { public static void main(String[] args) { ForkJoinPool pool = new ForkJoinPool(); CountTask task = new CountTask(1,4); Future<Integer> result = pool.submit(task); try { System.out.println("计算结果=" + result.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } } class CountTask extends RecursiveTask<Integer>{ private static final long serialVersionUID = -7524245439872879478L; private static final int THREAD_HOLD = 2; private int start; private int end; public CountTask(int start,int end){ this.start = start; this.end = end; } @Override protected Integer compute() { int sum = 0; //如果任务足够小就计算 boolean canCompute = (end - start) <= THREAD_HOLD; if(canCompute){ for(int i=start;i<=end;i++){ sum += i; } }else{ int middle = (start + end) / 2; CountTask left = new CountTask(start,middle); CountTask right = new CountTask(middle+1,end); //执行子任务 left.fork(); right.fork(); //获取子任务结果 int lResult = left.join(); int rResult = right.join(); sum = lResult + rResult; } return sum; } }
参考: Fork/Join框架详解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义