JUC--黑马|JUC并发编程 -- Fork / Join 框架(JDK1.7 新加入的线程池实现)
1. Fork / Join 框架 1.1 介绍
- Fork/Join 是 JDK 1.7 加入的新的线程池实现,它体现的是一种分治思想,适用于能够进行任务拆分的 cpu 密集型运算
- 所谓的任务拆分,是将一个大任务拆分为算法上相同的小任务,直至不能拆分可以直接求解。跟递归相关的一些计算,如归并排序、斐波那契数列、都可以用分治思想进行求解
- Fork/Join 在分治的基础上加入了多线程,可以把每个任务的分解和合并交给不同的线程来完成,进一步提升了运算效率
- Fork/Join 默认会创建与 cpu 核心数大小相同的线程池
示例代码:
package com.tian;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
@Slf4j(topic = "c.TestForkJoin2")
public class TestForkJoin2 {public static void main(String[] args) {ForkJoinPool pool = new ForkJoinPool(4);
// new MyTask(5)5+ new MyTask(4)4 + new MyTask(3)3 + new MyTask(2)2 + new MyTask(1)
System.out.println("计算的结果是: " + pool.invoke(new MyTask(5)));
}
}/**
* RecursiveTask: 有返回值
* RecursiveAction: 无返回值
*/
@Slf4j(topic = "c.MyTask")
class MyTask extends RecursiveTask {private final int n;
public MyTask(int n) {this.n = n;
}@Override
public String toString() {return "{" + n + '}';
}// 1~n 之间整数的和
@Override
protected Integer compute() {// 如果 n 已经为 1,可以求得结果了
if (n == 1) {log.debug("join() {}", n);
return n;
}// 将任务进行拆分(fork)
AddTask1 t1 = new AddTask1(n - 1);
t1.fork();
log.debug("fork() {} + {}", n, t1);
// 合并(join)结果
int result = n + t1.join();
log.debug("join() {} + {} = {}", n, t1, result);
return result;
}
}
运行结果:
文章图片
运行流程图示:
文章图片
1.3 优化任务拆分(难点)
package com.tian;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class TestForkJoin {public static void main(String[] args) {ForkJoinPool pool = new ForkJoinPool(4);
System.out.println(pool.invoke(new AddTask(1, 5)));
}
}@Slf4j(topic = "c.AddTask")
class AddTask extends RecursiveTask {// 起始数字
int begin;
// 结束数字
int end;
public AddTask(int begin, int end) {this.begin = begin;
this.end = end;
}@Override
public String toString() {return "{" + begin + "," + end + '}';
}@Override
protected Integer compute() {// 5,5
if (begin == end) {log.debug("join() {}", begin);
return begin;
}
// 4,5
if (end - begin == 1) {log.debug("join() {} + {} = {}", begin, end, end + begin);
return end + begin;
}
// 1,5 => mid = 3
int mid = (end + begin) / 2;
// 计算 1, 3
AddTask t1 = new AddTask(begin, mid);
t1.fork();
// 计算 4, 5
AddTask t2 = new AddTask(mid + 1, end);
t2.fork();
log.debug("fork() {} + {} = ?", t1, t2);
// 结果求和
int result = t1.join() + t2.join();
log.debug("join() {} + {} = {}", t1, t2, result);
return result;
}
}
运行结果:【JUC--黑马|JUC并发编程 -- Fork / Join 框架(JDK1.7 新加入的线程池实现)】
文章图片
运行流程图示:
文章图片
推荐阅读
- JUC中ReentrantLock和AbstractQueuedSynchronizer原理解析
- JUC--CLH同步队列
- 【黑马程序员】永不凋零的蓝莲花
- Java|Java JUC ConcurrentLinkedQueue解析
- 【JUC】ArrayBlockingQueue之Condition应用
- 【JUC】CountDownLatch共享节点队列
- Java|Java JUC ReentrantReadWriteLock解析
- 【JUC】两图理解Condition的等待、唤醒逻辑
- 黑马头条-2020版-前端部分-前端项目初始化.p001
- Java JUC LockSupport概述