不使用 java.util.Date 的 Java 纳秒时间

问题描述 投票:0回答:2

我需要极其精确和准确的时间以及尽可能少的垃圾收集 (GC),最好是每天 1 次。

System.currentTimeMillis()
不够精确,
System.nanoTime()
不是准确的时间来源。唯一能给我我想要的东西的是
java.util.Date.getTime()
但它不是一个静态方法,所以每次我需要精确和准确的时间时我都必须创建一个新的
Date
对象,这会导致 GC 被更频繁地触发。

有谁知道

Date
类如何获得准确且精确的时间?我希望采用 Date 的方法并对其进行定制以最小化对象创建。总结我的问题,请参阅以下内容:

long nanosSinceEpoch;
nanosSinceEpoch = System.currentTimeMillis(); // Not precise
nanosSinceEpoch = System.nanoTime();          // Not accurate
nanosSinceEpoch = new Date().getTime();       // Too many objects

编辑:

我不知道为什么我认为

System.currentTimeMillis()
new Date().getTime()
不同,但事实证明它们是相同的。但遗憾的是,这并没有解决我的问题。

此外,来自

getNano()
java.time.Instant
似乎只有毫秒分辨率。

java date time garbage-collection precision
2个回答
7
投票

Instant.now

Java 9 带来了

Clock
的全新实现,能够以比 Java 8 的 Clock
毫秒
功能更精细的精度捕获当前时刻。

Instant instant = Instant.now() ;

让我明确一点:Java 的

所有
版本中的Instant类都能够保持纳秒为单位的值。但在版本 8 中,捕获当前时刻仅限于毫秒。

您应该研究当前计算机设备的硬件时钟的功能。我相信你会发现目前的传统硬件无法精确到纳秒级的跟踪时间。

在 macOS Sierra 上使用 Oracle JDK 9.0.4 时,我看到当前时刻以 微秒 为单位捕获,六位十进制小数秒。

System.nanoTime() 不是准确的时间来源

不,准确性不是问题。那里的问题是

System.nanoTime()
旨在跟踪经过的时间,而不是当前日期时间。此功能仅跟踪自任意未记录的起点以来的纳秒计数。在某些实现中,该起点可能是主机启动时,但您不能依赖于此。

再次强调,如上所述,我们并不是在谈论以纳秒为单位的增量,因为当前的传统计算机硬件不具备这种能力。


关于 java.time

java.time框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如

java.util.Date
Calendar
SimpleDateFormat

Joda-Time项目现在处于维护模式,建议迁移到java.time类。

要了解更多信息,请参阅 Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

您可以直接与数据库交换 java.time 对象。使用符合 JDBC 4.2 或更高版本的 JDBC 驱动程序。不需要字符串,不需要

java.sql.*
类。

从哪里获取java.time类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是 java.time 未来可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如

Interval
YearWeek
YearQuarter
more


1
投票

System.nanoTime() 不是准确的时间来源

这并不完全正确。其准确性“高度依赖于系统”。如果你可以控制你的硬件和操作系统,原则上你可以用它构建一个高精度时钟,即使在旧的 java 版本上也是如此。 自从

JDK-8068730

已经实现以来,较新的时间 API 通过遵循可用的最准确的操作系统时钟来使您免受这些复杂性的影响,这反过来又会进行必要的硬件功能检测,以确定 TSC 是否足够可靠以供使用作为时间源。

© www.soinside.com 2019 - 2024. All rights reserved.