文章目录
写在前面
开发中遇到这么一个业务场景:有100个任务我需要执行,这几个任务之间并没有什么关联,只需要在这些任务都执行完毕之后,我需要一个最终的结果。
此时,就需要使用ForkJoin线程池来完成多个任务并行的工作了,大大的提高了运行速度!
直接上代码
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
/**
* 在项目中使用forkjoin
*/
public class UseForkJoin {
public static void main(String[] args) {
// 创建一个可以同时执行20个线程的ForkJoinPool
ForkJoinPool pool = new ForkJoinPool(20);
// 初始化需要执行的数据
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 200; i ++) {
list.add(i);
}
pool.invoke(new ExecuteService(list, 0, list.size()));
System.out.println("活跃线程数:"+pool.getActiveThreadCount());
System.out.println("窃取任务数:"+pool.getStealCount());
}
}
/**
* 业务逻辑类
*/
class ExecuteService extends RecursiveAction {
// 拆分粒度
static final int THRESHOLD = 4;
List<Integer> list;
// 开始
int start;
// 结束
int end;
public ExecuteService(List<Integer> list, int start, int end) {
this.list = list;
this.start = start;
this.end = end;
}
@Override
protected void compute() {
// 判断是否需要继续分割任务
int length = end - start;
if(length <= THRESHOLD){
for (int i = start; i <= end; i++) {
// 执行业务逻辑
System.out.println(Thread.currentThread().getName() + "计算" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
else {
// 继续拆分
int middle = (start + end) / 2;
ExecuteService left = new ExecuteService(list, start, middle);
left.fork(); // 执行任务
ExecuteService right = new ExecuteService(list, middle + 1, end);
right.fork(); // 执行任务
left.join(); // 必须得join
right.join();
}
}
}
解析
这里我们让业务类继承的是RecursiveAction ,它是可以执行返回值是void的任务,同时jdk也提供了可以有返回值的类RecursiveTask。