使用ForkJoin实现串行 并行(List集合形式)

#需求 需要根据把 属性合并不能重复 对应关系 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;
       }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我有一个抱枕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值