java中时钟跳动_Java中是否存在一致(单调)时钟实现?

Java默认的Clock基于System.currentTimeMillis()可能不保证单调递增,导致时间跳转问题。可以利用System.nanoTime()创建单调时钟,或者使用Time4J库的TemporalType.CLOCK.from(SystemClock.MONOTONIC)来实现。在服务器环境中,通过正确配置ntpd服务也能确保系统时间单调。当需要记录事件历史时,考虑使用序列号而非时钟。
摘要由CSDN通过智能技术生成

默认java.time.Clock实现基于System.currentTimeMillis()。如这里所讨论的,

Monotonically increasing time in Java?,

它不能保证是单调的。

事实上,我经常遇到一个情况,系统时间自动调整到几秒钟,而java时钟也跳回来。

//now() returns 2016-01-13T22:34:05.681Z

order.setCreationTime(Instant.now());

//... something happens, order gets cancelled

//now() returns 2016-01-13T22:34:03.123Z

//which is a few seconds before the former one,

//even though the call was performed later - in any reasonable sense.

//The recorded history of events is obviously inconsistent with the real world.

order.setCancelationTime(Instant.now());

当不能依赖时间只在一个方向上时,不可能执行时间敏感的事情,例如记录和分析事件历史。

上述帖子说System.nanoTime()是单调的(如果底层系统支持它)。所以,如果我想将我的代码放在java.time API上,那我需要在内部使用nanoTime的Clock来确保单向流程。也许这样的事情会起作用。还是不行?

public class MyClock() extends java.time.Clock {

private final long adjustment;

public MyClock() {

long cpuTimeMillis = System.nanoTime()/1000000;

long systemTimeMillis = System.currentTimeMillis();

adjustment = systemTimeMillis - cpuTimeMillis;

}

@Override

public long millis() {

long currentCpuTimeMillis = System.nanoTime()/1000000;

return currentCpuTimeMillis + adjustment;

}

}

它只是一个素描,而不是一个完整的时钟实现。我认为一个正确的实现也应该对构造函数中传递的另一个Clock进行调整,而不是直接针对currentTimeMillis()。

或者,是否有任何地方可以实现这样一个单调的时钟实现?我想呢肯定有很多人面对同样的问题。

结论

感谢您的鼓舞人心的意见和答案。有几个有趣的点分散在评论中,所以我将在这里总结一下。

单调时钟

对于我原来的问题,是的,可以让单调时钟不受系统时间的影响。这样的实现可以基于我上面提出的System.nanoTime()。过去曾经有这样的问题,但今天的现代制度应该是正常的。这种方法已经在Time4J库中实现了,它们的单调时钟可以很容易地转换成java.time.Clock:

Clock clock = TemporalType.CLOCK.from(SystemClock.MONOTONIC);

适当的系统时间控制

可以配置系统时间管理(unix / linux中的ntpd),以便系统时间几乎不会回退(如果需要的话,系统时间就会慢下来),那么可以依靠系统时间是单调的, Java是必需的。

我会这样做,因为我的应用程序是服务器端,我可以控制时间。实际上,我在一个实验环境中遇到了异常,我自己安装了(只有表面上的领域知识),而且它只是使用ntpdate客户端(如果时间不同步,它可以向后跳),而不是ntpd可以进行配置,使其不会跳回)。

3.使用序列而不是时钟

当需要跟踪强烈关系之前发生的事情,从原子生成的序列中提供事件序列号并不依赖于挂钟更安全。一旦应用程序在几个节点上运行(这不是我的情况),它就成为唯一的选择。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值