gpt4 book ai didi

java - Java中是否有任何一致的(单调的)时钟实现?

转载 作者:IT老高 更新时间:2023-10-28 20:35:53 25 4
gpt4 key购买 nike

默认的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;
}
}

这只是一个草图,而不是完整的时钟实现。而且我认为正确的实现还应该针对构造函数中传递的另一个时钟执行调整,而不是直接针对 currentTimeMillis()。

或者,是否已经有这样的单调时钟实现在任何地方可用?我想肯定有很多人面临同样的问题。

结论

感谢您鼓舞人心的评论和回答。评论中散布着几个有趣的点,所以我在这里总结一下。

1.单调时钟

至于我最初的问题,是的,可以有不受系统时间向后跳跃影响的单调时钟。这样的实现可以基于我上面建议的 System.nanoTime() 。过去这种方法曾经存在问题,但在今天的现代系统上应该可以正常工作。这种方法已经在例如 Time4J 中实现。库,它们的单调时钟可以很容易地转换为 java.time.Clock:

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

<强>2。适当的系统时间控制

可以配置系统时间管理(unix/linux 中的 ntpd),这样系统时间几乎不会向后移动(如果需要,它会变慢),然后可以依赖系统时间是单调的,并且Java 中不需要时钟魔法。

我会这样做,因为我的应用程序是服务器端的,我可以控制时间。实际上,我在自己安装的实验环境中遇到了异常(仅对领域有肤浅的了解),并且它仅使用 ntpdate 客户端(如果时间不同步,它可以向后跳转),而不是 ntpd(可以配置为不跳回)。

3.使用序列而不是时钟

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

最佳答案

正如@the8472 所说,关键是让机器(jvm 运行的地方)的时间同步正确。

如果您对客户端进行编程,那么依赖系统时钟确实很危险。但是对于服务器,有一个解决方案 - 您可能需要考虑使用具有严格配置的 NTP。

In here他们基本上解释了NTP会减慢时间,不会倒退。

还有 this NTP documentation说:

Sometimes, in particular when ntpd is first started, the error might exceed 128 ms. This may on occasion cause the clock to be set backwards if the local clock time is more than 128 s in the future relative to the server. In some applications, this behavior may be unacceptable. If the -x option is included on the command line, the clock will never be stepped and only slew corrections will be used.

关于java - Java中是否有任何一致的(单调的)时钟实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34778744/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com