J'ai étudié ce qui est nécessaire pour le traitement asynchrone avec SpringBoot, donc dans ce document,
J'ai résumé sur.
java8 + Spring Boot 2.1.0 + lombok
build.gradle est le suivant
buildscript {
    ext {
        springBootVersion = '2.1.0.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
    mavenCentral()
}
dependencies {
    implementation('org.springframework.boot:spring-boot-starter-web')
    compileOnly('org.projectlombok:lombok')
    testImplementation('org.springframework.boot:spring-boot-starter-test')
}
Créez un processus qui dort correctement
@Slf4j
@Service
public class AsyncService {
    @Async("Thread2")
    public CompletableFuture<String> findName(String name, Long sleepTime) throws InterruptedException {
        log.warn("Async function started. processName: " + name + "sleepTime: " + sleepTime);
        Thread.sleep(sleepTime);
        
        //Utilisez la valeur de retour que vous souhaitez réellement utiliser dans le Completable Future afin de pouvoir gérer le traitement asynchrone.
        return CompletableFuture.completedFuture(name);
    }
}
Implémentez un contrôleur approprié pour gérer le traitement asynchrone
@Slf4j
@RequiredArgsConstructor
@RestController
public class FindNameContoller {
    private final AsyncService asyncService;
    @GetMapping("/users/")
    public List<String> findUsers() throws Exception {
        long start = System.currentTimeMillis();
        long heavyProcessTime = 3000L;
        long lightProcessTime = 1000L;
        log.warn("request started");
        CompletableFuture<String> heavyProcess = asyncService.findName("heavy", heavyProcessTime);
        CompletableFuture<String> lightProcess = asyncService.findName("light", lightProcessTime);
        //Processus à exécuter lorsque heavyProcess est terminé
        heavyProcess.thenAcceptAsync(heavyProcessResult -> {
            log.warn("finished name=" + heavyProcessResult + ", sleep = " + heavyProcessTime);
        });
        //Processus à exécuter lorsque lightProcess est terminé
        lightProcess.thenAcceptAsync(lightProcessResult -> {
            log.warn("finished name=" + lightProcessResult + ", sleep = " + lightProcessTime);
        });
        //Lorsque le processus spécifié est terminé, les processus suivants seront exécutés.
        CompletableFuture.allOf(heavyProcess, lightProcess).join();
        //Créer une valeur de retour
        List<String> names = new ArrayList<>();
        names.add(heavyProcess.get());
        names.add(lightProcess.get());
        Thread.sleep(10L);
        long end = System.currentTimeMillis();
        //Sortie de l'heure de l'ensemble du processus
        log.warn("request finished. time: " + ((end - start))  + "ms");
        return names;
    }
}
Décrire les différents paramètres de la classe Application principale
@EnableAsync
@SpringBootApplication
public class AsyncTrainingApplication {
    public static void main(String[] args) {
        SpringApplication.run(AsyncTrainingApplication.class, args);
    }
    @Bean("Thread1") //Ce paramètre n'est pas spécifié et n'est pas utilisé
    public Executor taskExecutor1() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(20);
        executor.setThreadNamePrefix("Thread1--");
        executor.initialize();
        return executor;
    }
    @Bean("Thread2") //Définir ici"Thread2"Est défini sur @Async et ce paramètre est utilisé
    public Executor taskExecutor2() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5); //La taille de filetage par défaut. Lorsqu'il déborde, il indique la taille de la capacité de la file d'attente
        executor.setQueueCapacity(1); //La taille de la file d'attente. Augmenter le filetage à la taille maximale du pool en cas de débordement
        executor.setMaxPoolSize(500); //Définition de la quantité de fil à augmenter S'il dépasse cette valeur, le processus sera rejeté et une exception se produira.
        executor.setThreadNamePrefix("Thread2--");
        executor.initialize();
        return executor;
    }
    @Bean("Reject") //Avec ce paramètre, la mise en file d'attente ne peut pas être effectuée, le thread ne peut pas être augmenté et une exception RejectedExecutionException se produit.
    public Executor rejectTaskExecuter() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setQueueCapacity(0);
        executor.setMaxPoolSize(1);
        executor.setThreadNamePrefix("Reject--");
        executor.initialize();
        return executor;
    }
}
Lorsque vous exécutez le processus, le journal suivant apparaît et vous pouvez voir qu'il s'exécute de manière asynchrone
2018-11-27 20:19:13.181  WARN 8711 --- [nio-8080-exec-5] c.e.asynctraining.FindNameContoller      : request started
2018-11-27 20:19:13.181  WARN 8711 --- [TaskExecutor-31] com.example.asynctraining.AsyncService   : Async function started. processName: heavysleepTime: 3000
2018-11-27 20:19:13.182  WARN 8711 --- [TaskExecutor-32] com.example.asynctraining.AsyncService   : Async function started. processName: lightsleepTime: 1000
2018-11-27 20:19:14.187  WARN 8711 --- [onPool-worker-2] c.e.asynctraining.FindNameContoller      : finished name=light, sleep = 1000
2018-11-27 20:19:16.182  WARN 8711 --- [onPool-worker-2] c.e.asynctraining.FindNameContoller      : finished name=heavy, sleep = 3000
2018-11-27 20:19:16.194  WARN 8711 --- [nio-8080-exec-5] c.e.asynctraining.FindNameContoller      : request finished. time: 3013ms
Recommended Posts