Реализация параллельного потока, чтобы получить все данные об ученике - PullRequest
0 голосов
/ 08 июня 2018

Я написал сервис для получения полной информации о студентах всех классов.Служба работает нормально, но проблема в том, что получение полной информации занимает слишком много времени.Мой код соответствует приведенному ниже.

List<StudentsDetails> allStudentsDetails = Lists.newArrayList();

List<ClassDetails> allClassDetailsDetails = getAllClassDetails();

allClassDetailsDetails.forEach(classDetailsDetails-> {
    StudentsDetails studentsDetails = new StudentsDetails();
    studentsDetails.setClassName(classDetailsDetails.getClassName());
    List<Student> allStudents = studentService.getAllStudentsByClass(classDetailsDetails.getClassName());
    studentsDetails.setAllStudents(allStudents);        
    allStudentsDetails.add(studentsDetails);
});

Мой вопрос

Хорошо ли использовать параллельный поток Java8 в этом сценарии, действительно ли это повышает производительность, а также какя могу реализовать параллельный поток в этом подходе.

Ответы [ 3 ]

0 голосов
/ 09 июня 2018

Код медленный из-за доступа к БД.

Во-первых, вы должны проиндексировать свою БД.

Во-вторых, если база данных ваших студентов не очень высокая, я рекомендую вам получить ее в одномСнимок:

List<Student> findStudentByClassNameIn(List<String> classNames);

Затем сопоставьте ваших учеников с вашим классом.

// Map class name with its student
Map<String, List<Student>> stdMap = listStudents().stream().collect(groupingBy(Student::getClassName), toList());

List<StudentsDetails> allStudentsDetails = allClassDetailsDetails.stream()
        .parallel()
        .map(c -> new StudentDetails(stdMap.get(c.getClassName()))
        .collect(toList());

В-третьих, если данные ваших учеников слишком велики, чтобы их можно было сделать за один снимок, то разбейте, чтобы получить, например,30 классов данных одновременно.

0 голосов
/ 09 июня 2018

Попробуйте мою библиотеку AbacusUtil .Это должно быть в десятки раз быстрее, чем код в оригинальном вопросе:

List<StudentsDetails> allStudentsDetails = StreamEx.of(allClassDetailsDetails).parallel(maxThreadNum) // genernally maxThreadNum = 30 is a good choice.
    .map(c -> new StudentsDetails(c.getClassName(), studentService.getAllStudentsByClass(c.getClassName())))
    .toList();
0 голосов
/ 08 июня 2018

Так вы распараллеливаете операцию, но выигрыш в производительности не может быть гарантирован, поскольку это также зависит от внешней базы данных.

Function<ClassDetails, StudentsDetails> fetchStudentDetials = classDetailsDetails -> {
    StudentsDetails studentsDetails = new StudentsDetails();
    studentsDetails.setClassName(classDetailsDetails.getClassName());
    List<Student> allStudents = studentService.getAllStudentsByClass(classDetailsDetails.getClassName());
    studentsDetails.setAllStudents(allStudents);
    return studentsDetails;
};

List<StudentsDetails> allStudentsDetails = allClassDetailsDetails
        .parallelStream()
        .map(fetchStudentDetials)
        .collect(toList());
...