사용자 도구

사이트 도구


springframework:async

Spring @Async

설정

  • Java 8 이후 버전에서는 AsyncConfigurer interface를 구현하면 된다. default method 라서 원하는 것만 선택구현가능함.
@EnableAsync
public class SpringAsyncConfig extends AsyncConfigurerSupport {
 
    // 기본 taskExecutor 
    @Bean // @Bean 필수
    @Override
    public Executor getAsyncExecutor() {
        return new ThreadPoolTaskExecutor(); // 객체 설정해줄것.
    }
 
}

ThreadPoolTaskExecutor 설정

Cached Thread Pool 효과

  • corePoolSize 는 적게 혹은 0, maxPoolSize=Interger.MAX_VALUE, queueCapacity를 0으로 만들면 Cached Thread Pool 처럼 작동한다.
  • 기본 CorePoolSize 만큼 풀을 생성하고,
  • 필요하면 쓰레드풀을 최대 maxPoolSize 만큼 증가시키고
  • 안 사용하는 시간이 KeepAliveSeconds가 지나면 쓰레드를 없앤다.
  • cachedThreadPool 은 느려지는 태스크 실행시 쓰레드 갯수가 폭증해서 시스템을 다운시킬 수도 있다.
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setThreadNamePrefix("XXXX-");
threadPoolTaskExecutor.setCorePoolSize(0);
threadPoolTaskExecutor.setMaxPoolSize(Integer.MAX_VALUE);
threadPoolTaskExecutor.setQueueCapacity(0);
threadPoolTaskExecutor.setKeepAliveSeconds(60);
threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
threadPoolTaskExecutor.setAwaitTerminationSeconds(15);

MDC 사용하기

ThreadPoolTaskExecutor 설정에 Decorator 지정

@Override
public Executor getAsyncExecutor() {
  ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  executor.setTaskDecorator(new MdcTaskDecorator());
  executor.initialize();
  return executor;
}

MdcTaskDecorator.java

class MdcTaskDecorator implements TaskDecorator {
 
  @Override
  public Runnable decorate(Runnable runnable) {
    // Right now: Web thread context !
    // (Grab the current thread MDC data)
    Map<String, String> contextMap = MDC.getCopyOfContextMap();
    return () -> {
      try {
        // Right now: @Async thread context !
        // (Restore the Web thread context's MDC data)
        if (contextMap != null) {
            MDC.setContextMap(contextMap);
        }
 
        runnable.run();
      } finally {
        MDC.clear();
      }
    };
  }
}

CompletableFuture 지원

@Async
public CompletableFuture<User> findUser(String user) throws InterruptedException {
    logger.info("Looking up " + user);
    String url = String.format("https://api.github.com/users/%s", user);
    User results = restTemplate.getForObject(url, User.class);
    Thread.sleep(1000L);
    return CompletableFuture.completedFuture(results); //IT IS completedFuture
}
springframework/async.txt · 마지막으로 수정됨: 2023/01/26 10:20 저자 kwon37xi