简体   繁体   中英

Custom ThreadPoolTaskExecutor with Spring Boot Async

I have a Spring Boot application which is responsible for answering requests via REST. I also push metrics about my application call. Since this is a separate task and I have to response users immediately, I want to make that metrics publishing asynchronously. So I've used that:

ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("MyApp-");
executor.initialize();
return executor;

However, this one uses SimpleAsyncTaskExecutor and does not reuse any threads.

1) How can I use ConcurrentTaskExecutor instead of SimpleAsyncTaskExecutor ?

2) Which implementation could best fit for my needs?

To make your custom Executor work, make sure it's registered as a Bean, and reference it on the method annotated with @Async :

@Bean(name = "transcodingPoolTaskExecutor")
public Executor transcodingPoolTaskExecutor() {
    final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(2);
    executor.setMaxPoolSize(2);
    executor.setQueueCapacity(500);
    executor.setThreadNamePrefix("transcoder-");
    executor.initialize();
    return executor;
}

And in the @Service which is holding the method:

@Async("transcodingPoolTaskExecutor")
public void transcodeVideo(UUID fileId) {
    mediaFileService.transcodeVideo(fileId);
}

You can also redefine the default executor by creating a Configuration class which implements AsyncConfigurer . Something like this:

@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {
    @Value("${async.executor.corePoolSize:20}")
    private int corePoolSize;

    @Value("${async.executor.maxPoolSize:100}")
    private int maxPoolSize;

    @Value("${async.executor.queueCapacity:50}")
    private int queueCapacity;

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix("Async Executor -");
        executor.initialize();
        return executor;
    }
}

In this case you wouldn't need to specify the executor name in @Async annotation. Spring will take executor, which you defined in AsyncConfig .

It's very similar to the solution provided by yglodt, but in this case you don't need to specify the name of executor in every @Async annotation, so it removes potential misspelling in the executor name.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM