JUC-12-forkJoin

JUC-12-forkJoin

1. 简介

在JDK1.7中出现,用于并行执行效率。(必须要在大数据量中使用forkJoin)

本质:分而治之

mark

2.特点

  • 工作窃取

mark

3. 具体使用

mark

  • RecursiveAction:没有返回值
  • RecursiveTask:有返回值

现在有一个需求:需要计算0到十亿的和!

(以下有三种方式去求解)

  1. 单纯for循环求和(直接被开除)
1
2
3
4
5
6
7
8
9
public static void test1(){
long sum = 0;
long start = System.currentTimeMillis();
for (int i = 0; i < 10_0000_0000; i++) {
sum += i;
}
long end = System.currentTimeMillis();
System.out.println("执行了" + (end-start) + "时间"+",sum是"+sum);
}
  1. 使用forkJoin(可以调节切分的点)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void test2() throws ExecutionException, InterruptedException {
long start = System.currentTimeMillis();

// 使用forkJoin必须要new 一个 forkJoinPool
ForkJoinPool forkJoinPool = new ForkJoinPool();
Test test = new Test(0L, 10_0000_0000L);
// 提交任务
ForkJoinTask<Long> submit = forkJoinPool.submit(test);

// 获取结果
Long sum = submit.get();

long end = System.currentTimeMillis();
System.out.println("执行了" + (end-start) + "时间" + sum);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

// 如何使用forkJoin
// 1. forkjoinPool 通过它来执行
// 2. 计算任务 execute(ForkJoinTask<?> task)
// 3. 类要继承:extends RecursiveTask<>


import java.util.concurrent.RecursiveTask;

public class Test extends RecursiveTask<Long> {

private Long start;
private Long end;

// 临界值
private Long temp = 10000L;

public Test(Long start, Long end) {
this.start = start;
this.end = end;
}


// 计算方法
@Override
protected Long compute() {
if ((end-start) < temp){
Long sum = 0l;
for (Long i = start; i < end; i++) {
sum += i;
}
return sum;

}else {
// 分支合并计算 forkJoin
long mid = (start + end)/2;
// 拆分任务,同时压入队列
Test test1 = new Test(start, mid);
test1.fork();
Test test2 = new Test(mid + 1, end);
test2.fork();

// 获取子结果
return test1.join() + test2.join();
}
}
}
  1. 使用Stream流计算(建议去读一下源码)
1
2
3
4
5
6
7
8
9
public static void test3(){
long start = System.currentTimeMillis();
// Stream并行流
// rangeClosed (]
long sum = LongStream.rangeClosed(0L, 10_0000_0000L).parallel().reduce(0, Long::sum);

long end = System.currentTimeMillis();
System.out.println("执行了" + (end-start) + "时间");
}
打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2019-2022 Zhuuu
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信