Home > Net >  How to use Async in Spring Boot?
How to use Async in Spring Boot?

Time:11-30

Below is my code.

With my below code, different thread ids are not getting created.

The output has same thread id.

@Controller
@RequestMapping(value = "/Main")
public class MyController 
{
   @Autowired
   private MyService myService;
   
   @PostMapping("/Sub")
   @ResponseBody
   public String readInput(@RequestBody String name)
   {
       for (int i = 0;i<5;i  )
       {
           myService.asyncMethod();
       }
       return "Success";
   }
}

With my below code, different thread ids are not getting created.

@Repository
@Configuration
@EnableAsync
public class MyService {

    @Bean(name = "threadPoolTaskExecutor")
    public Executor threadPoolTaskExecutor() {
      return new ThreadPoolTaskExecutor();
    }
     
    @Async("threadPoolTaskExecutor")
    public void asyncMethod() {
      System.out.println("Thread "   Thread.currentThread().getId()  " is running");
    }
}

CodePudding user response:

First of all, it is impossible to judge whether the thread pool is used by the thread id. You can set the thread prefix and judge by the log

  1. Configure thread pool
@Slf4j
@Configuration
public class ThreadExecutorConfig {

    @Autowired
    private ThreadPoolProperties threadPoolProperties;

    @Bean(name = "taskExecutor")
    public ExecutorService executorService() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(threadPoolProperties.getCorePoolSize());
        executor.setMaxPoolSize(threadPoolProperties.getMaxPoolSize());
        executor.setQueueCapacity(threadPoolProperties.getQueueSize());
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setThreadNamePrefix("myThread-");
        executor.initialize();
        log.info("threadPoolConfig;corePoolSize:[{}];maxPoolSize:[{}];queueSize:[{}]",
                threadPoolProperties.getCorePoolSize(),
                threadPoolProperties.getMaxPoolSize(),
                threadPoolProperties.getQueueSize());
        return executor.getThreadPoolExecutor();
    }
}
  1. Use @Async annotations on methods
    @Async(value = "taskExecutor")
    @Override
    public void asyncSave(OperationLogModel entity) {
        if (log.isDebugEnabled()) {
            log.debug("thread:{};entity:{}", Thread.currentThread().getName(), entity.toString());
        }
        entity.setCreateTime(LocalDateTime.now());
        super.save(entity);
    }
  1. View log enter image description here

CodePudding user response:

Good question! The answer is in ThreadPoolTaskExecutor. Its default corePoolSize is one.

@Bean(name = "threadPoolTaskExecutor")
public Executor threadPoolTaskExecutor() {
    ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
    threadPoolTaskExecutor.setCorePoolSize(3);//or any (positive) integer that suits you.
    return threadPoolTaskExecutor;
} 

..will behave more as we expect:

Thread 127 is running
Thread 128 is running
Thread 128 is running
Thread 129 is running
Thread 127 is running
  • Related