Skip to content
Advertisement

Multiple RestTemplate calls for each Id in a List

I need to make multiple RestTemplate calls for each of the Id in a List<Ids>. What is the best way to perform this?

I have used parallelStream(). Below code snippet is a similar scenario.

List<Integers> employeeIds;
employeeIds.parallelStream().
.map(empId -> employeeService.fetchEmployeedetails(empId))
.collect(Collectos.toList());

employeeService.fetchEmployeedetails is a kind of restCall which will fetch all the employeeDetails.

Is there any other way to tune the performance?

Advertisement

Answer

.parallelStream() does not guarantee multi threading since it will create only threads equals to number of cores you have. To really enforce multiple threads doing this simultaneously, you need to use .parallelStream() with ForkJoinPool.

High Performance using 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
    }
}

This will ensure that parallelStream() creates max 50 threads instead of depending on number of cores of your system. Make sure you do not forget to shutdown() of the pool in finally block. and also do not forget .get(); which triggers execution of the thread.

ArrayList is not thread-safe to modify but synchronized() will provide that safety. Since the adding to the list is quite minor operation, it will not hold the thread long either.

You will see tremendous performance improvement with this approach.

How to choose optimal number for threads

Too many threads would cause context switch and slow down the process. Too less threads keep the system underutilized. The optimum thread count is often around 10 times the number of cores you have. Also depends on time you are going to spend within the thread. I generally pass an environment variable, so that i can tune the number 50 when I want. But I have reached 50 after quite a bit of experiment on a quad core instance that we have.

    @Value("#{systemEnvironment['parallelism'] ?: 50}")
    protected int parallelism;

and then use ForkJoinPool forkJoinPool = new ForkJoinPool(getParallelism());

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement