我需要制作多个RestTemplate
要求每个Id
in a List<Ids>
。执行此操作的最佳方法是什么?
我用过parallelStream()
。下面的代码片段是类似的场景。
List<Integers> employeeIds;
employeeIds.parallelStream().
.map(empId -> employeeService.fetchEmployeedetails(empId))
.collect(Collectos.toList());
employeeService.fetchEmployeedetails
是一种restCall
这将获取所有employeeDetails
.
还有其他方法可以调整性能吗?
.parallelStream()
不保证多线程,因为它只会创建等于您拥有的核心数量的线程。要真正强制多个线程同时执行此操作,您需要将 .parallelStream() 与ForkJoinPool
.
使用 ForkJoinPool 实现高性能
List<Employee> employees = new ArrayList();
ForkJoinPool forkJoinPool = new ForkJoinPool(50);
try {
forkJoinPool.submit(() -> employeeIds.parallelStream().forEach(empId -> {
Employee em = employeeService.fetchEmployeedetails(empId);
synchronized(employees) {
employees.add(em);
}
})).get();
} catch (Exception e) {
e.printStackTrace();
throw new BusinessRuleException(ErrorCodeEnum.E002501.value(), e.getMessage());
} finally {
if (forkJoinPool != null) {
forkJoinPool.shutdown(); // always remember to shutdown the pool
}
}
这将确保parallelStream()最多创建 50 个线程而不是取决于系统的核心数量。确保您不要忘记shutdown()
最后块中的池的。并且也不要忘记.get();
这会触发线程的执行。
ArrayList 的修改不是线程安全的,但是synchronized()
将提供这种安全。由于添加到列表是相当小的操作,因此它也不会长时间占用线程。
通过这种方法,您将看到性能的巨大提升。
如何选择最佳线程数
太多的线程会导致上下文切换并减慢进程。线程太少会导致系统利用率不足。最佳线程数通常是您拥有的核心数的 10 倍左右。还取决于您将在线程中花费的时间。我通常会传递一个环境变量,这样我就可以在需要时调整数字 50。但在我们拥有的四核实例上进行了大量实验后,我已经达到了 50。
@Value("#{systemEnvironment['parallelism'] ?: 50}")
protected int parallelism;
然后使用ForkJoinPool forkJoinPool = new ForkJoinPool(getParallelism());
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)