9

Could you tell me what are the default parameters for Spring @Async ThreadPoolTaskExecutor or how can I find them one my own?

What are the default values for maxPoolSize, corePoolSize, and queueCapcity?

Should I override them to improve my application or is it just fine to use default values?

Pasha
  • 1,768
  • 6
  • 22
  • 43

6 Answers6

9

I assume you would like to use @EnableAsync (javadoc) annotation to support async tasks execution in spring.

In this case the documentation states the following:

By default, Spring will be searching for an associated thread pool definition: either unique org.springframework.core.task.TaskExecutor bean in the context, or an java.util.concurrent.Executor bean named "taskExecutor" otherwise.

If neither of the two is resolvable, a org.springframework.core.task.SimpleAsyncTaskExecutor will be used to process async method invocations.

Now if you want to provide your own customization, you can define (implement) an AsyncConfigurer (javadoc) that basically allows to define an executor and exception handler (out of scope for this question).

Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97
  • 2
    Yes, but what are the default values and does it worh it to define a custom configuration for @Async? – Pasha Sep 18 '19 at 08:44
  • This depends on your context. If you've defined TaskExecutor (and provided its defaults somewhere else) - it will take it. So default is up to you. If its not resolved, SimpleAsyncTaskExecutor fires up a new Thread for each task (as appears in its documentation again). This is pretty wasteful so probably you don't really want to use SimpleAsyncTaskExecutor.... – Mark Bramnik Sep 18 '19 at 08:48
  • 1
    You should definitely use a custom configuration if you intend to use more than eight threads. The default configuration has a queue size of two billion. That queue will never be full und therefore no more than eight threads will ever be created. – Sven Döring Jul 15 '21 at 14:31
6

Regarding ThreadPoolTaskExecutor's implementation. You can check it at their github repository. ThreadPoolTaskExecutor

private int corePoolSize = 1;

private int maxPoolSize = Integer.MAX_VALUE;

private int queueCapacity = Integer.MAX_VALUE;
Tran Ho
  • 1,442
  • 9
  • 15
3

I think you need @EnableAsync to enable @Async annotation and this annotation will use default implementation SimpleAsyncTaskExecutor

SimpleAsyncTaskExecutor implementation does not reuse any threads, rather it starts up a new thread for each invocation. However, it does support a concurrency limit which will block any invocations that are over the limit until a slot has been freed up.

You can define your own ThreadPoolTaskExecutor like

@Configuration
public class ThreadConfig {

    @Bean("otherExecutor")
    public TaskExecutor threadPoolTaskExecutor() {

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(16);
        executor.setMaxPoolSize(32);
        executor.initialize();

        return executor;
    }
}

And refer to this in the @Async

@Async("otherExecutor")
void doSomething(String s) {
    // this will be executed asynchronously by "otherExecutor"
}

sendon1982
  • 9,982
  • 61
  • 44
2

According to Spring sources @EnableAsync annotation configures acctually SimpleAsyncTaskExecutor and that doesn’t reuse threads and the number of threads used at any time aren’t limited by default.

There's a queue between that process which submits jobs and the thread pool. If all threads are occupied, the job will just be queued. If the queue is full and the threads are also occupied, then the new task will be rejected. There are couple of rejection policies you can choose (for example. caller runs).

If you are looking for true pooling look at SimpleThreadPoolTaskExecutor and ThreadPoolTaskExecutor

mmalkiew
  • 21
  • 2
2

The bean name for the task executor that @Async uses is applicationTaskExecutor

The properties for applicationTaskExecutor are defined in TaskExecutionProperties

private int queueCapacity = Integer.MAX_VALUE;
private int coreSize = 8;
private int maxSize = Integer.MAX_VALUE;
Grigory Zhadko
  • 1,484
  • 1
  • 19
  • 33
Kevin D.
  • 67
  • 1
  • 9
1

Defined in TaskExecutionProperties. Autoconfigure uses this file instead of ThreadPoolTaskExecutor as mentioned in other answer

Dileep
  • 775
  • 5
  • 20
AlexQin
  • 11
  • 2