#spring #multithreading #spring-boot #rest #asynchronous
#весна #многопоточность #spring-boot #отдых #асинхронный
Вопрос:
Ниже приведен мой код.
В приведенном ниже коде разные идентификаторы потоков не создаются.
Выходные данные имеют тот же идентификатор потока.
@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";
}
}
В приведенном ниже коде разные идентификаторы потоков не создаются.
@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");
}
}
Ответ №1:
Прежде всего, невозможно судить, используется ли пул потоков по идентификатору потока. Вы можете установить префикс потока и судить по журналу
- Настройка пула потоков
@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();
}
}
- Используйте @Async аннотации к методам
@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);
}
Ответ №2:
Хороший вопрос! Ответ находится в ThreadPoolTaskExecutor . По умолчанию corePoolSize
используется единица.
@Bean(name = "threadPoolTaskExecutor")
public Executor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(3);//or any (positive) integer that suits you.
return threadPoolTaskExecutor;
}
.. будет вести себя так, как мы ожидаем:
Thread 127 is running
Thread 128 is running
Thread 128 is running
Thread 129 is running
Thread 127 is running
Комментарии:
1. Даже после установки размера основного пула (до 10), он по-прежнему печатает тот же идентификатор потока!
2. Попробуйте добавить
Thread.sleep(1000);
asyncMethod
. @user2488578