Spring Framework上的multithreading(或异步)计算

我正在学习Spring Framework,它非常棒。

我想使用JAVAmultithreading,但我不知道如何使用Spring Framework。

这是服务代码:

//StudentService.java public List loadGradesForAllStudents(Date date) { try{ List grades = new ArrayList(); List students = loadCurrentStudents(); // LOAD FROM THE DB for(Student student : students) { // I WANT TO USE MULTITHREAD FOR THIS PART // LOAD FROM DB (MANY JOINS) History studentHistory = loadStudentHistory(student.getStudentId(), date); // CALCULATION PART Grade calculatedGrade = calcStudentGrade(studentHistory, date); grades.add(calculatedGrade); } return grades; } catch(Exception e) { ... return null; } } 

没有multithreading,它很慢。

我想for循环会导致缓慢,但我不知道如何解决这个问题。 如果给我一个有用的链接或示例代码,我会很感激。

我发现loadStudentHistory方法与calcStudentGrade(大约30ms)相比非常慢(大约300ms)。

在具有并发用户的应用程序中使用multithreading这是一个坏主意,因为现在每个查询使用多个线程和多个连接,而不是让每个请求使用一个线程和一个连接。 它不会随着用户数量的增长而扩展。

当我看你的例子时,我看到两个可能的问题:

1)在应用程序和数据库之间有太多的往返行程,其中每次行程都需要时间。

2)不清楚每个查询是否使用单独的事务(您没有说明在示例代码中划分事务的位置),如果您的查询每个都创建自己的事务可能是浪费,因为每个事务都有相关的开销用它。

使用multithreading对#1没有多大帮助(如果它确实有助于它会对数据库施加更多负载)并且对#2没有影响或使其变得更糟(取决于当前的事务范围;如果你有之前在同一事务中的查询,使用多个线程,它们必须在不同的事务中)。 如前所述,它不会扩大规模。

我的建议:

1)使服务具有事务性(如果尚未进行),以便它所做的一切都在一个事务中。 删除exception捕获/返回null的东西(这会干扰Spring如何使用exception来回滚事务)并引入exception处理程序,以便捕获并记录从控制器抛出的任何内容。 这将最大限度地减少您创建事务的开销,并使您的exception处理更加清晰。

2)创建一个带回学生列表的查询。 这样查询就会被发送到数据库一次,然后以块的forms读回结果集结果(根据结果集上的获取大小)。 您可以自定义查询以仅返回所需内容,这样您就不会有过多的连接数。 对查询运行explain-plan并确保它使用索引。 您将获得更快的查询和更少的往返次数,这将大大提高速度。

简单的解决方案称为流 ,这使您可以并行迭代,例如:

 students.stream().parallel().forEach( student -> doSomething(student)); 

这将给你一个明显的性能提升它不会删除数据库查询开销…如果你的数据库管理系统需要大约300毫秒来返回结果….好吧……你要么在数据库上使用ORM或者您的查询非常低效,我建议您重新分析当前的解决方案