Какой вариант лучше?Конфигурация @Async с или без threadPoolExecutor? - PullRequest
0 голосов
/ 24 мая 2019

Какая польза от определения исполнителя потоков вручную в аннотации @Async весной? Когда мы не определяем executor, @Async работает лучше.

Вариант использования: Я создал ручной пул потоков с максимальным размером пула 50. Если мы пропустим 200 запросов, он обработает только до 50 запросов. Но если мы не определили ручной исполнитель потоков для @Async, он работает нормально.

@Async("messageQueueExecutor") - Останавливается после максимального размера пула

@Async - отлично работает

ThreadPoolConfig.java

package config;

import java.util.concurrent.Executor;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration
@PropertySource("classpath:threadpool-config.yml")
public class ThreadPoolConfig {

    /* Message Queue Thread Pool */
    /* start */
    @Value("${task.execution.pool.message-queue.core-size}")
    private int mqCorePoolSize;
    @Value("${task.execution.pool.message-queue.max-size}")
    private int mqMaxPoolSize;
    @Value("${task.execution.pool.message-queue.queue-capacity}")
    private int mqQueueCapacity;
    @Value("${task.execution.pool.message-queue.keep-alive}")
    private int mqKeepAliveSeconds;
    @Value("${task.execution.pool.message-queue.allow-core-thread-timeout}")
    private boolean mqAllowCoreThreadTimeOut;
    @Value("${task.execution.pool.message-queue.name}")
    private String mqThreadName;

    @Bean("messageQueueExecutor")
    public Executor messageQueueExecutor() {
        return threadPoolTaskExecutor(mqMaxPoolSize, mqMaxPoolSize, mqQueueCapacity, mqKeepAliveSeconds, mqAllowCoreThreadTimeOut, mqThreadName);
    }
    /* end */

    private ThreadPoolTaskExecutor threadPoolTaskExecutor(int corePoolSize, int maxPoolSize, 
            int queueCapacity, int keepAliveSeconds, 
            boolean allowCoreThreadTimeOut, String threadName) {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
        threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
        threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
        threadPoolTaskExecutor.setKeepAliveSeconds(keepAliveSeconds);
        threadPoolTaskExecutor.setAllowCoreThreadTimeOut(allowCoreThreadTimeOut);
        threadPoolTaskExecutor.setThreadNamePrefix(threadName);
        threadPoolTaskExecutor.initialize();
        threadPoolTaskExecutor.setRejectedExecutionHandler((runnable, executor) -> {
            executor.execute(runnable);
        });
        return threadPoolTaskExecutor;
    }   

}

application.properties

task.execution.pool.message-queue.max-size: 42
task.execution.pool.message-queue.allow-core-thread-timeout: true
task.execution.pool.message-queue.core-size: 7
task.execution.pool.message-queue.keep-alive: 60
task.execution.pool.message-queue.queue-capacity: 11
task.execution.pool.message-queue.name: messagequeue-threadpool-

1 Ответ

1 голос
/ 24 мая 2019

Ручной Thread Executor, чтобы иметь лучший контроль, специфичный для вашей конфигурации приложения.

В частности, к числу потоков, поскольку вы настроили максимальный размер пула 50, исполнитель НЕ ДОПУСКАЕТ более 50. Это кристально ясно!

Однако, помимо вашей конфигурации для максимального размера пула, это также ограничено системным процессором.

...