0%

java | Fork/Join

Fork/Join 体现了分而治之的思想,适用于能够进行任务拆分的 CPU 密集型计算。

所谓的任务拆分,是将一个大任务拆分为算法上相同的小任务,直至不能拆分可以直接求解。

Fork/Join 在分治的基础上加入了多线程,可以把每个人物的分解和合并交给不同的线程来完成,进一步提升了运行效率。

Fork/Join 默认会创建与 CPU 核心数大小相同的线程池。

使用

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
package com.redisc;

import lombok.extern.slf4j.Slf4j;

import java.time.DayOfWeek;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.concurrent.*;

@Slf4j(topic = "c.Test")
public class Run {

public static void main(String[] args) throws InterruptedException, ExecutionException {
ForkJoinPool pool = new ForkJoinPool(4);
System.out.println(pool.invoke(new MyTask(5)));
}
}

@Slf4j(topic = "c.MyTask")
class MyTask extends RecursiveTask<Integer> {
private int n;

public MyTask(int n) {
this.n = n;
}

@Override
public String toString() {
return "{" + n + "}";
}

@Override
protected Integer compute() {
// 终止条件
if (n == 1) {
log.debug("join() {}", n);
return 1;
}
MyTask t1 = new MyTask(n - 1);
t1.fork(); // 让一个线程去执行任务
log.debug("fork() {} + {}", n, t1);
int result = n + t1.join(); //获取任务结果
log.debug("join() {} + {} = {}", n, t1, result);
return result;
}
}

输出

1
2
3
4
5
6
7
8
9
10
13:26:54.812 [ForkJoinPool-1-worker-1] DEBUG c.MyTask - fork() 5 + {4}
13:26:54.812 [ForkJoinPool-1-worker-2] DEBUG c.MyTask - fork() 4 + {3}
13:26:54.812 [ForkJoinPool-1-worker-0] DEBUG c.MyTask - fork() 2 + {1}
13:26:54.812 [ForkJoinPool-1-worker-3] DEBUG c.MyTask - fork() 3 + {2}
13:26:54.815 [ForkJoinPool-1-worker-0] DEBUG c.MyTask - join() 1
13:26:54.816 [ForkJoinPool-1-worker-0] DEBUG c.MyTask - join() 2 + {1} = 3
13:26:54.816 [ForkJoinPool-1-worker-3] DEBUG c.MyTask - join() 3 + {2} = 6
13:26:54.816 [ForkJoinPool-1-worker-2] DEBUG c.MyTask - join() 4 + {3} = 10
13:26:54.816 [ForkJoinPool-1-worker-1] DEBUG c.MyTask - join() 5 + {4} = 15
15

优化改进

使用场景过少,不多说了。

请我喝杯咖啡吧~