I have used this tutorial and it's github project as a base for this SSCCE.
For unknown reason, methods marked as @Async
ran from a @Scheduled
method always execute synchronously.
I am looking for a fix or workaround to make the code from performTask()
run asynchonously.
The classes below:
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();
}
}
}
Produce the following synchronouse result:
+ 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]
The problem was not setting the corePoolSize
property of ThreadPoolTaskExecutor
.
By default the corePoolSize
is 1
, and the amount of threads increases only when the queue is full. Since my queue was infinite, no additional threads in the pool were ever created.
I ended up doing:
exec.setCorePoolSize(Runtime.getRuntime().availableProcessors()+1);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.