gpt4 book ai didi

java - Java中的准确计时

转载 作者:行者123 更新时间:2023-12-01 16:46:41 24 4
gpt4 key购买 nike

如何在Java中获得准确的计时?我知道Thread.sleep()是不准确的,并导致InterruptedExceptions。我正在尝试制作一个物理模拟器,我想拥有准确的代码。
到目前为止,这是我的代码:

public class FreeFall() {
public static void main(String[] args) {
double height = Double.parseDouble(args[0]);
double xi = height;
int counter = 0;
while (true) {
height = xi + 9.8 / * counter * counter;
System.out.println(height);
counter++;
Thread.sleep(1000);
}
}
}

最佳答案

tl; dr

Java的常规实现不是实时系统。因此,您不能指望确定性性能。

如果您坚持确定性的时间,请找出real-time Java的实现。

相似问题:Java - alternative to thread.sleep

Thread.sleep

您可以要求睡眠时间为纳秒级,但由于当前计算机硬件的限制,您可能无法入睡。参见the other sleep method以纳秒为单位的第二个参数。

Thread.sleep( 0L , 300L ) ;  // Ask to sleep 300 nanoseconds.


如下所述, Thread.sleep的行为永远不会确定可靠。内部CPU调度(例如乱序执行和超线程),JVM的OS调度,JVM的线程调度以及偶尔的垃圾回收等许多因素都会影响实际的执行时间。因此,除非移至 real-time Java实现,否则您永远不能指望可预测的执行。

System.nanoTime

要跟踪经过的时间,请调用 System.nanoTime。它具有纳秒级的分辨率,但精度可能不高。截至2018年,传统的计算机硬件时钟仅精确到微秒左右的范围,而不是纳秒。这对于诸如微基准测试(提示: JMH)之类的事情是有好处的。 System.nanoTime与告诉当前日期时间无关。返回的数字是某个未记录的原始时刻的计数(以我的经验,自从JVM启动以来,但不能保证)。 64位数字可能会在连续运行几十年后超负荷运行。

long start = System.nanoTime() ; // Just some progressively incrementing number of nanoseconds. NOT the current date-time.
long stop = System.nanoTime() ;
long elapsed = ( stop - start ) ; // Calculate elapsed time in a resolution as fine as nanoseconds (though not likely precise beyond microseconds).


Instant

要使用 nanoseconds分辨率获取UTC中的当前时刻,请使用 java.time.Instant类。在Java 8中,当前时刻只能捕获到毫秒,但是在Java 9及更高版本中, fresh implementationClock可能会提供更高的分辨率。我看到在macOS Sierra上的Oracle JDK 9.0.4中捕获了 microseconds

Instant instant = Instant.now() ;  // Capture the current moment in UTC with a resolution of nanoseconds though likely with precision not as fine.



  2018-03-16T01:18:54.898583Z


Duration

我建议通常按原样使用 Instant对象。您可以通过 isBeforeisAfterequals方法进行比较。要计算经过的时间,请使用 Duration.between

Duration d = Duration.between( instantThen , Instant.now() ) ;  // A span of time not attached to the timeline, with a resolution of nanoseconds.


避免 System.currentTimeMillis​()

至于 System.currentTimeMillis​(),您可以忽略此方法。您最好改用 Instant

执行者

至于 TimerTimerTask,您应该知道这些类现在已成为旧版,被Java 5和更高版本中添加的更复杂的Executor框架所取代。请参见 the Oracle Tutorial

实时Java

即使使用执行器,您也无法期望执行过程中具有精确的瞬间精度。主机OS控制调度JVM,并且其性能可能会有所不同。在JVM中,线程是动态调度的,它们的性能可能会有所不同。特别是,垃圾收集可能会在特定时刻影响性能。

如果要确定执行时间,则需要获取 real-time Java的实现。当然,Java的常规实现(例如Oracle JDK和OpenJDK)不是 real-time systems



关于java.time

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

现在位于 Joda-Time中的 maintenance mode项目建议迁移到 java.time类。

要了解更多信息,请参见 Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为 JSR 310

您可以直接与数据库交换java.time对象。使用与 JDBC driver或更高版本兼容的 JDBC 4.2。不需要字符串,不需要 java.sql.*类。

在哪里获取java.time类?


Java SE 8Java SE 9和更高版本


内置的
标准Java API的一部分,具有捆绑的实现。
Java 9添加了一些次要功能和修复。

Java SE 6Java SE 7


ThreeTen-Backport中的许多java.time功能都已反向移植到Java 6和7。

Android


更高版本的Android捆绑了java.time类的实现。
对于早期的Android(<26), ThreeTenABP项目改编了ThreeTen-Backport(如上所述)。请参见 How to use ThreeTenABP…



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

关于java - Java中的准确计时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49247986/

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