System.currentTimeMillis()需配合逻辑实现频率控制,核心是记录上一次执行时间并比较当前时间差值是否达标;分固定间隔执行和防抖式控制两种模式,需注意避免时间相等判断、多线程同步及系统时间修改影响。

System.currentTimeMillis() 本身不直接实现频率控制,它只是返回当前时间毫秒值。要靠它配合逻辑判断来实现任务执行频率限制,核心是“记录上一次执行时间,与当前时间比较差值是否达到间隔要求”。
基础频率控制:固定间隔执行
适用于定时任务(如每5秒执行一次),需手动维护上次执行时间戳:
- 定义一个 long lastExecTime = 0 变量,初始化为 0 或 System.currentTimeMillis()
- 每次准备执行任务前,计算:long now = System.currentTimeMillis(); if (now - lastExecTime >= intervalMs) { 执行任务; lastExecTime = now; }
- 注意:intervalMs 是目标间隔(如 5000 表示 5 秒),不是“必须精确到毫秒”,而是“至少等待这么久”
防抖式控制:避免高频触发
适合事件驱动场景(如按钮连点、接口频繁调用),只允许在指定时间窗口内执行一次:
- 记录上一次“允许执行”的时间点(long nextAllowedTime = 0)
- 执行前检查:if (System.currentTimeMillis() >= nextAllowedTime) { 执行; nextAllowedTime = System.currentTimeMillis() + intervalMs; }
- 相比“记录上次执行时间”,这种方式更强调“下一次最早可执行时刻”,对突发流量更友好
注意事项和常见坑
- 不要用 == 判断时间相等:毫秒级时间几乎不可能完全相等,应使用 ≥ 或 ≤ 比较
- 注意 long 溢出风险极小但存在:System.currentTimeMillis() 返回的是自 1970-01-01 的毫秒数,292 百万年后才溢出,实际无需担心
- 多线程下需同步:如果多个线程共用同一个 lastExecTime,必须加锁(synchronized / AtomicIntegerLong / ReentrantLock)或改用线程安全结构
- 系统时间被修改会影响逻辑:比如 NTP 校时、用户手动调时间,可能导致间隔异常变短或变长;生产环境高精度场景建议考虑 System.nanoTime() 配合单调时钟思路(但 nanoTime 不适合跨进程或长时间跨度)
简单示例:每 3 秒最多执行一次的日志打印
long lastLogTime = 0;
long interval = 3000;
if (System.currentTimeMillis() - lastLogTime >= interval) {
System.out.println("执行任务:" + new Date());
lastLogTime = System.currentTimeMillis();
}


















