我有这个类
@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());
}
}
}
schedule()
方法必须每 5 秒执行一次,scheduleFuture()
方法必须每 30 秒执行一次。我对以下情况感到困惑:
我可以看到
schedule()
方法每5秒平安工作,然后当scheduleFuture()
开始运行,scheduleFuture()
由于 Future 的方法 获取 方法,保持阻塞。我对此很好,因为这是符合 Future API 的预期行为.我想:
Only the
scheduleFuture()
method should be blocked.
问题 : 我不明白为什么
scheduleFuture()
阻止另一个 schedule()
方法太!。我的意思是如果 scheduleFuture()
被屏蔽了,schedule()
仍然被封锁了!。它不能开始新的循环或执行。直到scheduleFuture()
再次解锁。为什么会出现这种情况?
我有 两个
@Scheduled
方法,每一个调用 两个不同 用 @Async
注释的方法一个 bean(如果 MyServiceImplAsync
类是 @Scope("prototype")
,情况相同提前致谢。
最佳答案
因为您正在阻塞用于调度这些任务的单个线程。来自 @EnableScheduling
:
In all of the above scenarios, a default single-threaded task executor is used. When more control is desired, a @Configuration class may implement SchedulingConfigurer. This allows access to the underlying ScheduledTaskRegistrar instance.
@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
关于spring - 为什么与 Future 的 get 一起使用的 @Schedule 方法会阻止其他 @Schedule 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25131052/