理解ScheduledExecutorService中scheduleAtFixedRate和scheduleWithFixedDelay的区别
scheduleAtFixedRate
每间隔一段时间执行,分为两种情况:
-
当前任务执行时间小于间隔时间,每次到点即执行;
/** * 任务执行时间(8s)小于间隔时间(10s) */ public class ScheduleTest { static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); public static void main(String[] args) { scheduler.scheduleAtFixedRate(new Runnable() { @Override public void run() { System.out.println("Start: scheduleAtFixedRate: " + new Date()); try { Thread.sleep(8000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("End : scheduleAtFixedRate: " + new Date()); } }, 0, 10 , SECONDS); } } output: Start: scheduleAtFixedRate: Sun Apr 28 14:36:00 CST 2019 End : scheduleAtFixedRate: Sun Apr 28 14:36:08 CST 2019 Start: scheduleAtFixedRate: Sun Apr 28 14:36:10 CST 2019 End : scheduleAtFixedRate: Sun Apr 28 14:36:18 CST 2019 Start: scheduleAtFixedRate: Sun Apr 28 14:36:20 CST 2019 End : scheduleAtFixedRate: Sun Apr 28 14:36:28 CST 2019 Start: scheduleAtFixedRate: Sun Apr 28 14:36:30 CST 2019 End : scheduleAtFixedRate: Sun Apr 28 14:36:38 CST 2019 ... 程序启动时间是14:36:00,以后每间隔10s执行一次(即14:36:10、14:36:20、14:36:30等)。
-
当前任务执行时间大于等于间隔时间,任务执行后立即执行下一次任务。相当于连续执行了。
/** * 任务执行时间(12s)大于间隔时间(10s) */ public class ScheduleTest { static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); public static void main(String[] args) { scheduler.scheduleAtFixedRate(new Runnable() { @Override public void run() { System.out.println("Start: scheduleAtFixedRate: " + new Date()); try { Thread.sleep(12000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("End : scheduleAtFixedRate: " + new Date()); } }, 0, 10 , SECONDS); } } output: Start: scheduleAtFixedRate: Sun Apr 28 14:30:13 CST 2019 End : scheduleAtFixedRate: Sun Apr 28 14:30:25 CST 2019 Start: scheduleAtFixedRate: Sun Apr 28 14:30:25 CST 2019 End : scheduleAtFixedRate: Sun Apr 28 14:30:37 CST 2019 Start: scheduleAtFixedRate: Sun Apr 28 14:30:37 CST 2019 End : scheduleAtFixedRate: Sun Apr 28 14:30:49 CST 2019 Start: scheduleAtFixedRate: Sun Apr 28 14:30:49 CST 2019 End : scheduleAtFixedRate: Sun Apr 28 14:31:01 CST 2019 程序启动时间是14:30:13,按理说应该每间隔10s执行一次(即14:30:23、14:30:33等),但由于任务执行时间长于10s,下一次的任务要开始的时候发现上次的任务还没有完成,因此阻塞等待,一旦发现上次的任务完成,就马上启动。表现出来就是任务延时启动,最终的效果就是连续执行。
scheduleWithFixedDelay
每当上次任务执行完毕后,间隔一段时间执行。不管当前任务执行时间大于、等于还是小于间隔时间,执行效果都是一样的。
/**
* 任务执行时间(8s)小于间隔时间(10s)
*/
public class ScheduleTest {
static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public static void main(String[] args) {
scheduler.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
System.out.println("Start: scheduleWithFixedDelay: " + new Date());
try {
Thread.sleep(12000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("End : scheduleWithFixedDelay: " + new Date());
}
}, 0, 10 , SECONDS);
}
}
output:
Start: scheduleWithFixedDelay: Sun Apr 28 14:27:59 CST 2019
End : scheduleWithFixedDelay: Sun Apr 28 14:28:07 CST 2019
Start: scheduleWithFixedDelay: Sun Apr 28 14:28:17 CST 2019
End : scheduleWithFixedDelay: Sun Apr 28 14:28:25 CST 2019
Start: scheduleWithFixedDelay: Sun Apr 28 14:28:35 CST 2019
End : scheduleWithFixedDelay: Sun Apr 28 14:28:43 CST 2019
Start: scheduleWithFixedDelay: Sun Apr 28 14:28:53 CST 2019
End : scheduleWithFixedDelay: Sun Apr 28 14:29:01 CST 2019
...
可以看出每个End后,等待了10秒,才启动下一次Start。
/**
* 任务执行时间(12s)大于间隔时间(10s)
*/
public class ScheduleTest {
static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public static void main(String[] args) {
scheduler.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
System.out.println("Start: scheduleWithFixedDelay: " + new Date());
try {
Thread.sleep(12000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("End : scheduleWithFixedDelay: " + new Date());
}
}, 0, 10 , SECONDS);
}
}
output:
Start: scheduleWithFixedDelay: Sun Apr 28 14:26:29 CST 2019
End : scheduleWithFixedDelay: Sun Apr 28 14:26:41 CST 2019
Start: scheduleWithFixedDelay: Sun Apr 28 14:26:51 CST 2019
End : scheduleWithFixedDelay: Sun Apr 28 14:27:03 CST 2019
Start: scheduleWithFixedDelay: Sun Apr 28 14:27:13 CST 2019
End : scheduleWithFixedDelay: Sun Apr 28 14:27:25 CST 2019
Start: scheduleWithFixedDelay: Sun Apr 28 14:27:35 CST 2019
End : scheduleWithFixedDelay: Sun Apr 28 14:27:47 CST 2019
...
可以看出每个End后,等待了10秒,才启动下一次Start。
参考
scheduleAtFixedRate vs scheduleWithFixedDelay
扩展
『注:本文来自博客园“小溪的博客”,若非声明均为原创内容,请勿用于商业用途,转载请注明出处http://www.cnblogs.com/xiaoxi666/』
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)