#需求 需要根据把 属性合并不能重复 对应关系 1L 2L 3L
import com.alibaba.fastjson.JSONObject;
import com.faw_qm.meta.domain.Student;
import com.faw_qm.meta.domain.Teacher;
import java.util.*;
import java.util.concurrent.*;
public class TestForkJoinPool extends RecursiveTask<Map<String,JSONObject>> {
//模拟需要串行 和 并行条件
//false 为串行 true 为并行
private boolean flag = false;
//超过 为串行
public static int threshold = 0;
//存储
public static List<Teacher> teachers = null;
//构造方法
public TestForkJoinPool(List<Teacher> teachers,int threshold) {
this.teachers = teachers;
this.threshold = threshold;
}
/**
* 返回服务 A 服务B 服务C 每个json数据
*/
@Override
protected Map<String,JSONObject> compute() {
//判断是否串行
flag = this.teachers.size() > threshold;
//串行
if(!flag){
//分工作
List<List<Teacher>> lists = averageAssign(this.teachers, threshold);
//分工
TestForkJoinPool leftTask = new TestForkJoinPool(lists.get(0),threshold);
TestForkJoinPool rightTask = new TestForkJoinPool(lists.get(1),threshold);
//执行
leftTask.fork();
rightTask.fork();
Map<String, JSONObject> map1 = leftTask.join();
Map<String, JSONObject> map2 = rightTask.join();
//合并数据
map1.putAll(map2);
return map1;
//并行
}else{
//模拟数据库对应数据 服务端
Map<String,JSONObject> map = new HashMap<>();
List<Student> students = new ArrayList<>();
Student student1 = new Student(1L,"name");
Student student2 = new Student(1L,"age");
Student student3 = new Student(2L,"name");
Student student4 = new Student(2L,"sex");
Student student5 = new Student(3L,"name");
Student student6 = new Student(3L,"ace");
students.add(student1);
students.add(student2);
students.add(student3);
students.add(student4);
students.add(student5);
students.add(student6);
//循环客户端 需要拼接服务端json
for (int i = 0 ; i< teachers.size() ; i++){
//创建唯一字段过滤
Set<String> set = new HashSet<>();
//循环客户端
Teacher teacher = teachers.get(i);
//循环服务端
for (int j = 0; j < students.size(); j++) {
Student student = students.get(j);
//判断对应关系
if(teacher.getId() == student.getSid())
{
//赋值
set.add(teacher.getKemu());
set.add(student.getSname());
}
}
//创建json
JSONObject json = new JSONObject();
set.forEach(s->{
json.put(s,"111");
});
map.put( "服务端:"+teacher.getId(),json);
}
return map;
}
}
/**
* 将一个List均分成n个list,主要通过偏移量来实现的
*
* @param source 源集合
* @param limit 最大值
* @return
*/
public static <T> List<List<T>> averageAssign(List<T> source, int limit) {
if (null == source || source.isEmpty()) {
return Collections.emptyList();
}
List<List<T>> result = new ArrayList<>();
int listCount = (source.size() - 1) / limit + 1;
int remaider = source.size() % listCount; // (先计算出余数)
int number = source.size() / listCount; // 然后是商
int offset = 0;// 偏移量
for (int i = 0; i < listCount; i++) {
List<T> value;
if (remaider > 0) {
value = source.subList(i * number + offset, (i + 1) * number + offset + 1);
remaider--;
offset++;
} else {
value = source.subList(i * number + offset, (i + 1) * number + offset);
}
result.add(value);
}
return result;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//创建线程池
ForkJoinPool forkjoinPool = new ForkJoinPool();
//模拟客户端数据
List<Teacher> teachers = new ArrayList<>();
Teacher teacher1 = new Teacher(1L,"age");
Teacher teacher2 = new Teacher(2L,"name");
Teacher teacher3 = new Teacher(3L,"name");
teachers.add(teacher1);
teachers.add(teacher2);
teachers.add(teacher3);
//生成任务
TestForkJoinPool task = new TestForkJoinPool(teachers,teachers.size()/2);
//执行一个任务
ForkJoinTask<Map<String, JSONObject>> result = forkjoinPool.submit(task);
//获取数据
Map<String, JSONObject> map = result.get();
//输出
for (Map.Entry<String, JSONObject> entry : map.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue().toJSONString());
}
}
}
**
详细解答:
```java
//模拟需要串行 和 并行条件
//false 为串行 true 为并行
private boolean flag = false;
//超过一半 为串行
public static int threshold = 0;
//存储
public static List<Teacher> teachers = null;
**
这段代码是初始化数据
//构造方法
/*
* teachers 数据集合
* threshold 可以操作的数量
*/
public TestForkJoinPool(List<Teacher> teachers,int threshold) {
this.teachers = teachers;
this.threshold = threshold;
}
如果超过数量了 就要分工作 比如 一个果园有1000颗树 一个人采摘太慢 然后就又分了leftTask(500棵树) 和rightTask(500棵树) 俩个人采摘
如果需要每人采摘250棵
//判断是否串行
flag = this.teachers.size() > threshold;
threshold 为250即可 然后又会创建TestForkJoinPool 线程自调用 调用
这里平均分工作用的是averageAssign 这个方法可以把list 拆分多个list
//执行
leftTask.fork();
rightTask.fork();
去执行 执行完毕 合并数据
Map<String, JSONObject> map1 = leftTask.join();
Map<String, JSONObject> map2 = rightTask.join();
//合并数据
map1.putAll(map2);
以上就是if 里的true解释
//判断是否串行
flag = this.teachers.size() > threshold;
//串行
if(!flag){
//分工作
List<List<Teacher>> lists = averageAssign(this.teachers, threshold);
//分工
TestForkJoinPool leftTask = new TestForkJoinPool(lists.get(0),threshold);
TestForkJoinPool rightTask = new TestForkJoinPool(lists.get(1),threshold);
//执行
leftTask.fork();
rightTask.fork();
Map<String, JSONObject> map1 = leftTask.join();
Map<String, JSONObject> map2 = rightTask.join();
//合并数据
map1.putAll(map2);
return map1;
//并行
}
else解答
else 就是每个人250颗树可以进行采摘的内容了 自行修改else内容就可以了
else{
//模拟数据库对应数据 服务端
Map<String,JSONObject> map = new HashMap<>();
List<Student> students = new ArrayList<>();
Student student1 = new Student(1L,"name");
Student student2 = new Student(1L,"age");
Student student3 = new Student(2L,"name");
Student student4 = new Student(2L,"sex");
Student student5 = new Student(3L,"name");
Student student6 = new Student(3L,"ace");
students.add(student1);
students.add(student2);
students.add(student3);
students.add(student4);
students.add(student5);
students.add(student6);
//循环客户端 需要拼接服务端json
for (int i = 0 ; i< teachers.size() ; i++){
//创建唯一字段过滤
Set<String> set = new HashSet<>();
//循环客户端
Teacher teacher = teachers.get(i);
//循环服务端
for (int j = 0; j < students.size(); j++) {
Student student = students.get(j);
//判断对应关系
if(teacher.getId() == student.getSid())
{
//赋值
set.add(teacher.getKemu());
set.add(student.getSname());
}
}
//创建json
JSONObject json = new JSONObject();
set.forEach(s->{
json.put(s,"111");
});
map.put( "服务端:"+teacher.getId(),json);
}
return map;
}