我有这个班级
@Service
@Profile("async")
public class MyServiceImplAsync implements MyService {
..
@Async
@Override
public void printGreetings(String name) {
//do something and sleep 10 seconds
}
@Async
@Override
public Future<String> doSomething(String text) {
//do something and sleep 25 seconds
return new AsyncResult<String>(text);
}
}
观察,这两种方法使用@Async
现在,我也有以下内容:
@Component
public class MySchedule {
..
@Scheduled(cron="*/5 * * * * ?")
public void schedule(){
logger.info("Schedule working at {}", simpleDateFormat.format( new Date() ));
this.myService.printGreetings("Manolito");
}
@Scheduled(cron="*/30 * * * * ?")
public void scheduleFuture(){
logger.info("Schedule Future working at {}", simpleDateFormat.format( new Date() ));
try {
logger.info("{}", this.myService.doSomething("manolito").get(26, TimeUnit.SECONDS));
}
catch (InterruptedException | ExecutionException | TimeoutException e) {
logger.error("Error: {}, Class: {}", e.getMessage(), e.getClass());
}
}
}
必须每5秒执行schedule()
方法,并且每30秒必须执行scheduleFuture()
方法。
我对以下情况感到困惑:
我可以看到schedule()
方法每隔5秒就会正常工作,然后当scheduleFuture()
开始运行时,scheduleFuture()
方法会因未来的而获得方法,仍然被阻止。我对此很好,因为它是符合Future API的预期行为。
我想:
只应阻止
scheduleFuture()
方法。
问题:我无法理解scheduleFuture()
阻止其他schedule()
方法的原因!我的意思是如果scheduleFuture()
被阻止,schedule()
也会被阻止!它无法启动新的循环或执行。直到scheduleFuture()
再次解锁为止。
为什么会这样?
我有两个 @Scheduled
方法,每个方法调用两个不同的方法,用bean的@Async
注释(如果{{{ 1}} class是MyServiceImplAsync
提前致谢。
答案 0 :(得分:5)
因为您阻止了用于安排这些任务的单个线程。来自@EnableScheduling
:
在所有上述场景中,都使用默认的单线程任务执行程序。当需要更多控制时,@ Configuration类可以实现SchedulingConfigurer。这允许访问底层的ScheduledTaskRegistrar实例。
@Configuration
@EnableScheduling
public class AppConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
}
@Bean(destroyMethod="shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(100);
}
}
如果遇到此类问题,最好配置日志框架以显示线程的名称。使用log4j,您需要将%t
添加到PatternLayout