@Scheduled 和@Async 在 spring-boot 中共享同一个线程池
@Scheduled and @Async are sharing same threadpool in spring-boot
我配置了两个不同的线程池,一个用于 @Scheduled
,另一个用于 @Async
。但是,我注意到 @Async
的线程池没有被使用。
这是调度程序配置
@Configuration
@EnableScheduling
public class SchedulerConfig implements SchedulingConfigurer {
private final int POOL_SIZE = 10;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
threadPoolTaskScheduler.setThreadNamePrefix("my-sched-pool-");
threadPoolTaskScheduler.initialize();
scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
}
}
这是异步的配置
@Configuration
@EnableAsync
public class AppConfig {
@Bean(name = "asyncTaskExecutor")
public TaskExecutor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(15);
executor.setMaxPoolSize(15);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("my-async-pool-");
executor.initialize();
return executor;
}
}
下面是我如何调用它们
@Scheduled(fixedRateString = "2000" )
public void schedule() {
log.debug("here is the message from schedule");
asyncMethod();
}
@Async("asyncTaskExecutor")
public void asyncMethod(){
log.info("here is the message from async");
}
这是日志
{"thread":"my-sched-pool-1","level":"DEBUG","description":"here is the message from schedule"}
{"thread":"my-sched-pool-1","level":"INFO","description":"here is the message from async"}
正如您所注意到的,两个日志都具有相同的调度程序池。但我希望看到第二个来自 async
如果您从相同的 class
调用 @Async
方法,它们被声明为您有效地绕过了 Spring 的代理机制,这就是您的示例不起作用的原因。尝试从使用 @Service
或任何其他 @Component
类型注释的单独 class
调用方法。
@Service
SomeScheduledClass {
private final SomeAsyncClass someAsyncClass;
public SomeScheduledClass(SomeAsyncClass someAsyncClass) {
this.someAsyncClass = someAsyncClass;
}
@Scheduled(fixedRateString = "2000" )
public void schedule() {
log.debug("here is the message from schedule");
someAsyncClass.asyncMethod();
}
}
@Service
SomeAsyncClass {
@Async("asyncTaskExecutor")
public void asyncMethod(){
log.info("here is the message from async");
}
}
我配置了两个不同的线程池,一个用于 @Scheduled
,另一个用于 @Async
。但是,我注意到 @Async
的线程池没有被使用。
这是调度程序配置
@Configuration
@EnableScheduling
public class SchedulerConfig implements SchedulingConfigurer {
private final int POOL_SIZE = 10;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
threadPoolTaskScheduler.setThreadNamePrefix("my-sched-pool-");
threadPoolTaskScheduler.initialize();
scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
}
}
这是异步的配置
@Configuration
@EnableAsync
public class AppConfig {
@Bean(name = "asyncTaskExecutor")
public TaskExecutor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(15);
executor.setMaxPoolSize(15);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("my-async-pool-");
executor.initialize();
return executor;
}
}
下面是我如何调用它们
@Scheduled(fixedRateString = "2000" )
public void schedule() {
log.debug("here is the message from schedule");
asyncMethod();
}
@Async("asyncTaskExecutor")
public void asyncMethod(){
log.info("here is the message from async");
}
这是日志
{"thread":"my-sched-pool-1","level":"DEBUG","description":"here is the message from schedule"}
{"thread":"my-sched-pool-1","level":"INFO","description":"here is the message from async"}
正如您所注意到的,两个日志都具有相同的调度程序池。但我希望看到第二个来自 async
如果您从相同的 class
调用 @Async
方法,它们被声明为您有效地绕过了 Spring 的代理机制,这就是您的示例不起作用的原因。尝试从使用 @Service
或任何其他 @Component
类型注释的单独 class
调用方法。
@Service
SomeScheduledClass {
private final SomeAsyncClass someAsyncClass;
public SomeScheduledClass(SomeAsyncClass someAsyncClass) {
this.someAsyncClass = someAsyncClass;
}
@Scheduled(fixedRateString = "2000" )
public void schedule() {
log.debug("here is the message from schedule");
someAsyncClass.asyncMethod();
}
}
@Service
SomeAsyncClass {
@Async("asyncTaskExecutor")
public void asyncMethod(){
log.info("here is the message from async");
}
}