ThreadPoolTaskExecutor core and max pool size

Viewed 135

I have a Spring Boot application where we have to make some http calls to a 3rd party REST service. We might have to make 1 call or thousands of calls.

I am using the @Async Spring Boot annotation and a CompletableFuture, something like this:

    long start = System.nanoTime();
    List<String> list = new ArrayList<>();
    List<CompletableFuture<List<String>>> allFutures = new ArrayList<>();
    for (int i = 0; i < 1000; i++) {
        allFutures.add(httpClient.getStringAsync("Hello"));
    }
    List<String> unwrappedFutures = allFutures.stream()
            .map(CompletableFuture::join)
            .flatMap(List::stream)
            .collect(Collectors.toList());

    list.addAll(unwrappedFutures);
    long duration = (System.nanoTime() - start) / 1_000_000;
    log.info("Done in {} msecs", duration);

This code takes about 2 minutes to make the 1000k calls to the getStringAsync() method which has a 1 second delay.

It takes the same amount of time to process either on my laptop which the "Runtime.getRuntime().availableProcessors()" shows has 12 cores or on the EKS cluster where the number of cores seems to be one now.

I think I have to configure the ThreadPoolTaskExecutor so that the more number of cores are available the less time it takes to process.

However, I am not really sure how one can determine the core, max pool size and the queue capacity.

I wonder if the pool size has to be equal to the number of items in the list? That is, if the list has 1000 items which means that we have to make 1000 calls to the remote service, do we need 1000 threads? That seems a lot.

1 Answers

Adding my findings:

If I set the ThreadPoolTaskExecutor core and max size to 12 which is the number of cores on my laptop, at least that's what the Runtime.getRuntime().availableProcessors() shows, the 1000K calls are made in an average of 1.4 minutes.

If I set the ThreadPoolTaskExecutor core and max size to 100, the 1000K calls are made in an average of 10 seconds.

If I set the ThreadPoolTaskExecutor core and max size to 1000, the 1000K calls are made in an average of 1.4 seconds. This sounds very appealing, however I am doing an isolated test on my laptop, in the real scenario there will be a lot of other events being processed so I don't think this would be ideal.

Related