进度弹簧的固定速率和固定延迟有什么不同?

我正在使用spring实现计划任务,我看到有2个类型的配置时间,计划再次从最新工作。 2配置这个配置有什么不同。

@Scheduled(fixedDelay = 5000) public void doJobDelay() { // do anything } @Scheduled(fixedRate = 5000) public void doJobRate() { // do anything } 

  • fixedRate:使Spring以定期的间隔运行任务,即使最后一次调用可能仍在运行。
  • fixedDelay:专门控制上次执行完成时的下一个执行时间。

在代码中:

 @Scheduled(fixedDelay=5000) public void updateEmployeeInventory(){ System.out.println("employee inventory will be updated once only the last updated finished "); /** * add your scheduled job logic here */ } @Scheduled(fixedRate=5000) public void updateEmployeeInventory(){ System.out.println("employee inventory will be updated every 5 seconds from prior updated has stared, regardless it is finished or not"); /** * add your scheduled job logic here */ } 

fixedRate:用于每n毫秒运行一次作业方法。 这项工作是否已完成上一项任务并不重要。

fixedDelay:用于按任务之间给定的n毫秒等待时间顺序运行作业方法。

何时使用“fixedRate” :如果不期望超出内存和线程池的大小,则fixedRate是合适的。 如果传入的任务没有快速完成,最终可能会出现“Out of Memory exception”

何时使用“fixedDelay”:如果每个正在运行的任务彼此相关并且需要在前一个任务完成之前等待,则fixedRate是合适的。 如果小心设置fixedDelay时间,它还将使运行的线程有足够的时间在新任务开始之前完成其作业

“fixedRate”:在开始下一次执行之前等待上一次执行开始时的X millis。 如果当前执行超过’fixedRate’间隔,则下一次执行将排队,但只有下一次执行。 它不会创建一系列排队执行

 private static int i = 0; @Scheduled(initialDelay=1000, fixedRate=1000) public void testScheduling() throws InterruptedException { System.out.println("Started : "+ ++i); Thread.sleep(4000); System.out.println("Finished : "+ i); } 

输出:

开始:1
完成:1 // 4秒后
开始:2 //立即按固定费率指定等待1秒
完成:2 // 4秒后
等等

“fixedDelay”:在开始下一次执行之前等待上一次执行结束时的X millis。 无论当前执行花费多少时间,在将“fixedDelay”间隔添加到当前执行的结束时间之后开始下一次执行。 它不会排队下次执行。

 private static int i = 0; @Scheduled(initialDelay=1000, fixedDelay=1000) public void testScheduling() throws InterruptedException { System.out.println("Started : "+ ++i); Thread.sleep(4000); System.out.println("Finished : "+ i); } 

输出:

开始:1
完成:1 // 4秒后启动:2 //按照fixedDelay中的指定等待1秒完成:2 // 4秒后启动:3 // 1秒后
等等

固定延迟 :专门控制上次执行完成时的下一个执行时间。

固定速率 :即使最后一次调用仍在运行,Spring也会定期运行任务。

应该澄清的一件事是, fixedRate并不意味着执行将以某个时间间隔开始。

如果一次执行花费太多时间(超过固定速率),则下一次执行将仅在前一次执行完成开始,除非提供了@Async@EnableAsync 。 以下源代码是Spring的ThreadPoolTaskScheduler实现的一部分,解释了原因:

 @Override public void run() { Date actualExecutionTime = new Date(); super.run(); Date completionTime = new Date(); synchronized (this.triggerContextMonitor) { this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime); if (!this.currentFuture.isCancelled()) { schedule(); } } } 

您可以看到只有在上一个任务完成后( super.run() ),才会安排下一个任务( schedule() )。 使用@Async@EnableAsyncsuper.run()是一个异步函数,它将立即返回,因此下一个任务不必等待前一个任务实际完成。