system.currenttimemillis() 是获取当前时间毫秒数的快照,用于构建时效性逻辑而非直接验证;常见做法是生成时计算过期时间点,校验时比较当前时间与该时间点;需警惕系统时钟漂移风险,高敏感场景应结合单调时钟、ntp同步、存储层过期机制等提升可靠性。

System.currentTimeMillis() 本身只是一个获取当前时间毫秒数的“快照”,它不直接实现时效性验证,但可以作为基础工具来构建时效性逻辑——关键在于你如何用它去计算、比较和判断。
用时间戳做有效期判断
最常见的场景是:某个数据(比如 token、验证码、缓存项)生成时记录一个过期时间点,后续校验时用 System.currentTimeMillis() 和该时间点比大小。
- 生成时:`long expireTime = System.currentTimeMillis() + 5 * 60 * 1000; // 5分钟有效期`
- 校验时:`if (System.currentTimeMillis() > expireTime) { /* 已过期 */ }`
注意系统时钟漂移带来的风险
如果服务器时间被手动调整或 NTP 同步异常,System.currentTimeMillis() 可能突增或回退,导致误判过期或延迟失效。
- 避免仅依赖单次调用做长期状态判断
- 对高敏感场景(如金融 token),可结合单调时钟(如
System.nanoTime()做相对耗时检测)辅助识别时钟倒退 - 分布式系统中建议统一使用 NTP 服务并监控时钟偏移
配合其他机制提升可靠性
单纯靠毫秒时间戳无法解决所有问题,常需组合设计:
- 与版本号/随机盐值结合,防止重放攻击
- 在 Redis 等存储中设置 EXPIRE,让过期由存储层保障,Java 层只做快速前置判断
- 对用户端传入的时间戳(如请求头里的 timestamp),必须服务端重新生成基准时间校验,不能信任客户端输入
简单示例:验证码时效检查
假设你把验证码和它的过期时间存在 Map 中(仅示意):
Map<string long> codeExpiry = new ConcurrentHashMap();
// 发送时
codeExpiry.put("123456", System.currentTimeMillis() + 180_000); // 3分钟
<p>// 校验时
Long expire = codeExpiry.get("123456");
if (expire == null || System.currentTimeMillis() > expire) {
throw new RuntimeException("验证码已失效");
}</p></string>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











