[JAVA] Exécuteurs de tâches séparés utilisés par @Async au printemps

Dans le traitement asynchrone avec @ Async, vous pouvez contrôler le nombre d'exécutions simultanées en exécutant ThreadPoolTaskExecutor. Cependant, si des processus importants et des processus moins importants sont gérés dans le même ThreadPool, lorsqu'un grand nombre de processus sans importance attendent d'être exécutés, même si vous essayez d'exécuter des processus importants, il sera difficile à exécuter. Faire.

Par conséquent, je voudrais diviser le TaskExecutor utilisé par le traitement et le gérer avec un autre ThreadPool.

Méthode de mise en œuvre

Définissez deux beans TaskExecutor. Les deux sont des ThreadPoolTaskExecutors et le nombre d'exécutions simultanées est de 1.

@SpringBootApplication
@EnableAsync
public class TaskApplication {

    public static void main(String[] args) {
        SpringApplication.run(TaskApplication.class, args);
    }

    @Bean
    TaskExecutor importantTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setMaxPoolSize(1);
        executor.setQueueCapacity(5);
        return executor;
    }

    @Bean
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setMaxPoolSize(1);
        executor.setQueueCapacity(5);
        return executor;
    }
}

La partie qui effectue le traitement asynchrone est implémentée comme suit. (Interface omise) Spécifiez le nom du TaskExecutor utilisé dans @ Async. En mettant un sommeil pendant 10 secondes dans le processus, l'état d'attente d'exécution est généré.

@Service
@Slf4j
public class TaskServiceImpl implements TaskService {

    @Async("importantTaskExecutor")
    @Override
    public void importantTask() {
        try {
            log.info("start important task");
            TimeUnit.SECONDS.sleep(10);
            log.info("end important task");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Async("taskExecutor")
    @Override
    public void task() {
        try {
            log.info("start normal task");
            TimeUnit.SECONDS.sleep(10);
            log.info("end normal task");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

J'ai confirmé l'opération avec le code suivant.

@RestController
@RequiredArgsConstructor
public class TaskAsyncController {

    private final TaskService taskService;

    @GetMapping("/")
    public String task() {
        taskService.task();
        taskService.task();
        taskService.task();
        taskService.task();
        taskService.importantTask();

        return "Success!!";
    }
}

Une fois exécutée, une méthode de tâche sera exécutée, mais les trois autres seront en attente d'exécution. Cependant, la méthode importantTask n'attend pas l'exécution et est exécutée immédiatement.

Vous pouvez maintenant voir qu'un autre ThreadPoolTaskExecutor est disponible.

Recommended Posts

Exécuteurs de tâches séparés utilisés par @Async au printemps
Annotations utilisées dans les outils de gestion des tâches Spring Boot
Afficher la tâche Gradle dans le projet Spring Boot
Inject Logger au printemps
Utilisez Interceptor au printemps
Microservices dans Spring Cloud
Obtenez des cookies au printemps