java中的精确计时

java中的精确计时,java,time,Java,Time,如何在Java中实现精确计时?我知道Thread.sleep()不准确,会导致中断异常。我正在尝试制作一个物理模拟器,我想得到准确的代码。 以下是我目前的代码: public class FreeFall() { public static void main(String[] args) { double height = Double.parseDouble(args[0]); double xi = height; int count

如何在Java中实现精确计时?我知道Thread.sleep()不准确,会导致中断异常。我正在尝试制作一个物理模拟器,我想得到准确的代码。 以下是我目前的代码:

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);
        }
    }
}

您可能希望利用时间戳,利用时间戳,它将为您提供自1970年1月1日以来经过的毫秒数

当你的物体开始下落时,记下一个时间戳。然后,在循环中,可以获取表示当前时间的时间戳。从
currentTime
中减去
startTime
,可以得到精确的毫秒数。例如,从这一点,您可以计算在给定恒定速度的情况下,您的对象在这段时间内应该下落多远


这种方法的好处在于,无论您是在快速还是慢速处理器上运行,因为时间戳反映的是实际的时间流逝与循环的迭代次数。

您可能希望利用时间戳,利用时间戳,这将为您提供自1970年1月1日以来经过的毫秒数

当你的物体开始下落时,记下一个时间戳。然后,在循环中,可以获取表示当前时间的时间戳。从
currentTime
中减去
startTime
,可以得到精确的毫秒数。例如,从这一点,您可以计算在给定恒定速度的情况下,您的对象在这段时间内应该下落多远

这种方法的好处在于,无论是在快速还是慢速处理器上运行,时间戳都反映了实际的时间流逝和循环的迭代次数。

tl;博士 Java的传统实现不是实时系统。因此您不能指望确定性性能

如果你坚持确定性的时间安排,那就寻找一个实现

类似问题:

Thread.sleep
您可以要求以纳秒的分辨率睡觉,但由于当前计算机硬件的限制,您可能无法获得。请参见获取纳秒的第二个参数

Thread.sleep( 0L , 300L ) ;  // Ask to sleep 300 nanoseconds.
Thread.sleep
的行为从来都不是确定可靠的,如下所述。许多因素,如内部CPU调度(如无序执行和超线程)、JVM的操作系统调度、JVM的线程调度以及偶尔的垃圾收集,都会影响实际执行时间。因此,除非您转向实现,否则您永远无法指望可预测的执行

System.nanoTime
要跟踪经过的时间,请调用。它的分辨率为纳秒,但不太可能精确。截至2018年,传统计算机硬件时钟的精度仅为微秒左右,而非纳秒。这对于微观基准测试(提示:)这样的事情是有好处的。
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
要以UTC的分辨率获取当前时刻,请使用类。在Java8中,当前时刻只能捕获到毫秒,但在Java9和更高版本中,of可以提供更高的分辨率。我在macOS Sierra上看到了Oracle JDK 9.0.4中的捕获

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

持续时间
我建议一般按原样使用对象。您可以通过、
isAfter
equals
方法进行比较。要计算经过的时间,请使用

避免
System.currentTimeMillis​()
至于,你可以忘记这个方法。您最好改用
即时

执行人 至于和
TimerTask
,您应该知道这些类现在是遗留的,被添加到Java5和更高版本的更复杂的Executor框架所取代。看

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

如果希望执行的时间具有确定性,则需要获得的实现。Oracle JDK和OpenJDK等Java的传统实现肯定不是这样


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

该项目现已启动,建议迁移到类

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

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

从哪里获得java.time类

  • ,及以后
    • 内置的
    • 标准JavaAPI的一部分,带有捆绑实现
    • Java9添加了一些次要功能和修复
    • 大部分java.time功能都在中向后移植到Java6和Java7
    • 更高版本的Android捆绑包实现了java.time类
    • 对于早期的Android(tl;dr Java的传统实现不是实时系统,因此不能指望确定性性能

      如果你坚持确定性的时间安排,那就寻找一个实现

      类似问题:

      Thread.sleep
      您可以要求以纳秒的分辨率睡觉,但由于当前计算机硬件的限制,您可能无法获得。请参阅获取纳秒的第二个参数

      Thread.sleep( 0L , 300L ) ;  // Ask to sleep 300 nanoseconds.
      
      //To create a new date LocalDate ld = LocalDate.Of(2018,March,26); //To print current date LocalDate.now();
 //To create a new time
LocalTime lt = LocalTime.Of(11,22);
   //To print current time
Local time.now();
   //To create a new date time
LocalDateTime ldt = LocalDateTime.Of(2018,March,26,11,22);
   //To print current date time
LocalDateTime.now();