SongHui.Club

多线程-Future Task

在开发中如果碰到处理稍大数据量的场景可以考虑使用多线程来提高效率. 用法如示例:

1.引入 math3(计算 μ δ)

 <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-math3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-math3</artifactId>
            <version>3.6.1</version>
        </dependency>

2.示例

import com.alibaba.fastjson.JSON;
import dintalk.cn.common.demo.Student;

import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

import org.apache.commons.math3.stat.StatUtils;
import org.apache.commons.math3.stat.descriptive.moment.StandardDeviation;


/**
 * @ClassName: FutureTaskDemo
 * @Description:
 * @Author: song hui
 * @Date: 2022/1/14
 */
public class FutureTaskDemo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        /**
         * 需求:
         *   统计 各个年级中,学生的分数处于 所在年级 所有学生分数计算的 μ +- 1.5δ 之外. 的学生
         */
        Map<String, Object> result = new HashMap<>();
        // 1. 获取 学生, 按照年级分组
        List<Student> studentList = getStudents();
        Map<String, List<Student>> studentMap = 			studentList.stream().collect(Collectors.groupingBy(Student::getGrade));

        // 2. 创建多线程 task, 处理数据
        Map<String, Future<Object>> allTaskMap = new HashMap<>();
        ExecutorService executor = Executors.newFixedThreadPool(studentMap.size());

        // 3. 按照年级 , 提交 task
        for (Map.Entry<String, List<Student>> gradeEntry : studentMap.entrySet()) {
            Future<Object> objectFuture = submitStudentTask(executor, gradeEntry.getValue());
            allTaskMap.put(gradeEntry.getKey(), objectFuture);
        }
        executor.shutdown();

        // 4. 所有线程执行完毕后,封装数据
        for (Map.Entry<String, Future<Object>> taskEntry : allTaskMap.entrySet()) {
            String grade = taskEntry.getKey();
            Future<Object> futureTask = taskEntry.getValue();
            List<Student> gradeStudents = (List<Student>) futureTask.get();
            result.put(grade, gradeStudents);
        }

        // 5. 看结果
        System.out.println(JSON.toJSONString(result));
    }

    private static Future<Object> submitStudentTask(ExecutorService executor, List<Student> studentList) {
        Callable<Object> callable = () -> {
            List<Student> result = new ArrayList<>();
            try {
                // 1. 获取 分数 数组
                double[] scoreArr = studentList.stream().mapToDouble(Student::getScore).toArray();

                // 2. 计算 μ 和 δ (使用 math3)
                double mean = StatUtils.mean(scoreArr);
                StandardDeviation standardDeviation = new StandardDeviation();
                double sigma = standardDeviation.evaluate(scoreArr);
                double left = mean - sigma * 1.5;
                double right = mean + sigma * 1.5;

                // 3. 判断异常
                result = studentList.stream().filter(e -> e.getScore() > right || e.getScore() < left)
                        .collect(Collectors.toList());

            } catch (Exception e) {
                // 异常处理 ...
            }
            return result;
        };
        return executor.submit(callable);
    }


    // 获取 学生列表
    private static List<Student> getStudents() {
        List<Student> list = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            Student student = new Student();
            student.setAge(i);
            student.setName("name" + i);
            student.setGrade(String.valueOf((i % 2) + 1));
            student.setScore(i * (i % 2) * 1.1);
            list.add(student);
        }
        return list;
    }


}

  

 

posted @ 2022-01-14 20:18  Mr.SongHui  阅读(174)  评论(0编辑  收藏  举报