Spring-boot @Async 不是 运行 @Scheduled
Spring-boot @Async not running with @Scheduled
我已经使用 this tutorial and it's github project 作为这个 SSCCE 的基础。
由于未知原因,@Scheduled
方法中标记为 @Async
运行 的方法始终同步执行。
我正在寻找一个修复或变通方法来使 performTask()
运行 中的代码异步。
下面的类:
Application.java
@SpringBootApplication
@EnableScheduling
@EnableAsync
public class Application implements AsyncConfigurer{
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class);
}
@Override
@Bean(name="asyncExecutor")
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor exec = new ThreadPoolTaskExecutor();
exec.setMaxPoolSize(Runtime.getRuntime().availableProcessors()*2);
exec.setThreadGroupName("MyCustomExecutor");
exec.setWaitForTasksToCompleteOnShutdown(true);
exec.setBeanName("asyncExecutor");
exec.initialize();
return exec;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SimpleAsyncUncaughtExceptionHandler();
}
}
MyAsyncService.java
@Service
public class MyAsyncService {
static AtomicInteger taskNoCounter = new AtomicInteger();
public MyAsyncService() {
}
@Async("asyncExecutor")
public void performTask() {
int delayMs = (int) (System.currentTimeMillis()%1000+1000);
int taskNo = taskNoCounter.incrementAndGet();
String taskInfo = "MyAsyncTask [taskNo=" + taskNo + ", delayMs=" + delayMs + ", threadId="+Thread.currentThread().getId()+"]";
System.out.println("+ start " +taskInfo);
try {
Thread.sleep(delayMs);
} catch (InterruptedException e) {
// empty on purpose
}
System.out.println("- end " +taskInfo);
}
}
ScheduledTasks.java
@Component
public class ScheduledTasks {
@Autowired
MyAsyncService service;
@Scheduled(fixedRate = 1000)
public void reportCurrentTime() {
for (int i=0; i<20; i++) {
service.performTask();
}
}
}
产生以下同步结果:
+ start MyAsyncTask [taskNo=1, delayMs=1874, threadId=16]
- end MyAsyncTask [taskNo=1, delayMs=1874, threadId=16]
+ start MyAsyncTask [taskNo=2, delayMs=1749, threadId=16]
- end MyAsyncTask [taskNo=2, delayMs=1749, threadId=16]
+ start MyAsyncTask [taskNo=3, delayMs=1498, threadId=16]
- end MyAsyncTask [taskNo=3, delayMs=1498, threadId=16]
+ start MyAsyncTask [taskNo=4, delayMs=1997, threadId=16]
- end MyAsyncTask [taskNo=4, delayMs=1997, threadId=16]
+ start MyAsyncTask [taskNo=5, delayMs=1994, threadId=16]
问题不是设置 ThreadPoolTaskExecutor
的 corePoolSize
属性。
默认corePoolSize
为1
,线程数量只有在队列满时才会增加。因为我的队列是无限的,池中没有创建额外的线程。
我最后做了:
exec.setCorePoolSize(Runtime.getRuntime().availableProcessors()+1);
我已经使用 this tutorial and it's github project 作为这个 SSCCE 的基础。
由于未知原因,@Scheduled
方法中标记为 @Async
运行 的方法始终同步执行。
我正在寻找一个修复或变通方法来使 performTask()
运行 中的代码异步。
下面的类:
Application.java
@SpringBootApplication
@EnableScheduling
@EnableAsync
public class Application implements AsyncConfigurer{
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class);
}
@Override
@Bean(name="asyncExecutor")
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor exec = new ThreadPoolTaskExecutor();
exec.setMaxPoolSize(Runtime.getRuntime().availableProcessors()*2);
exec.setThreadGroupName("MyCustomExecutor");
exec.setWaitForTasksToCompleteOnShutdown(true);
exec.setBeanName("asyncExecutor");
exec.initialize();
return exec;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SimpleAsyncUncaughtExceptionHandler();
}
}
MyAsyncService.java
@Service
public class MyAsyncService {
static AtomicInteger taskNoCounter = new AtomicInteger();
public MyAsyncService() {
}
@Async("asyncExecutor")
public void performTask() {
int delayMs = (int) (System.currentTimeMillis()%1000+1000);
int taskNo = taskNoCounter.incrementAndGet();
String taskInfo = "MyAsyncTask [taskNo=" + taskNo + ", delayMs=" + delayMs + ", threadId="+Thread.currentThread().getId()+"]";
System.out.println("+ start " +taskInfo);
try {
Thread.sleep(delayMs);
} catch (InterruptedException e) {
// empty on purpose
}
System.out.println("- end " +taskInfo);
}
}
ScheduledTasks.java
@Component
public class ScheduledTasks {
@Autowired
MyAsyncService service;
@Scheduled(fixedRate = 1000)
public void reportCurrentTime() {
for (int i=0; i<20; i++) {
service.performTask();
}
}
}
产生以下同步结果:
+ start MyAsyncTask [taskNo=1, delayMs=1874, threadId=16]
- end MyAsyncTask [taskNo=1, delayMs=1874, threadId=16]
+ start MyAsyncTask [taskNo=2, delayMs=1749, threadId=16]
- end MyAsyncTask [taskNo=2, delayMs=1749, threadId=16]
+ start MyAsyncTask [taskNo=3, delayMs=1498, threadId=16]
- end MyAsyncTask [taskNo=3, delayMs=1498, threadId=16]
+ start MyAsyncTask [taskNo=4, delayMs=1997, threadId=16]
- end MyAsyncTask [taskNo=4, delayMs=1997, threadId=16]
+ start MyAsyncTask [taskNo=5, delayMs=1994, threadId=16]
问题不是设置 ThreadPoolTaskExecutor
的 corePoolSize
属性。
默认corePoolSize
为1
,线程数量只有在队列满时才会增加。因为我的队列是无限的,池中没有创建额外的线程。
我最后做了:
exec.setCorePoolSize(Runtime.getRuntime().availableProcessors()+1);