将Java虚拟机与System.nanoTime同步

将java虚拟机与System.nanoTime()同步是否有意义?

我的意思是 :

  • 调用System.nanoTime()并将结果放入t1
  • A向B发送数据包
  • 当在B上接收到来自A的数据包时,B调用System.nanoTime()并将结果发送给A.
  • 当在A上接收到来自B的数据包时,A调用System.nanoTime()并将结果放入t3,将来自B的数据包中接收的时间放在t2中
  • timeshift =(t3-t1)/ 2-t2

使用System.nanoTime来做到这一点是正确的吗?

谢谢 !

使用System.nanoTime来做到这一点是正确的吗?

System.nanoTime()仅用于测量单个JVM中的时间差异 ,而不是跨多个JVM的绝对时间。

此方法只能用于测量经过的时间,与系统或挂钟时间的任何其他概念无关。 返回的值表示纳秒,因为某些固定但任意的原始时间(可能在将来,因此值可能为负)。 在Java虚拟机的实例中,此方法的所有调用都使用相同的原点; 其他虚拟机实例可能使用不同的来源。

要解决这个问题,通常你会使用System.currentTimeMillis() ,但这仍然受到两台计算机的OS时钟的限制。 使用NTP在计算机之间同步时间。

请参阅使用Java在服务器和Internet之间进行时间同步

你想要实现的目标并不完全清楚。

如果您正在尝试同步时钟,则可以使用专门的协议,例如NTP 。 nanoTime()在任何情况下都无用,因为它的值在JVM之间无法比较。

如果您正在尝试测量延迟,则重复测量往返( t3-t1 )并除以2。 为此,确实可以使用nanoTime()

System.nanoTime()相对于任意和未指定的时间点。 从我所看到的,它似乎来自计算机的正常运行时间。

这使得在两台机器上比较nanoTime非常困难。

 timeshift = (t3 + t1) / 2 - t2; // note the + instead of - 

您使用的公式可用于近似两台机器之间的差异,但它可以显示出巨大的差异。 解决这个问题的一种方法是执行1000次并取平均值或中位数,这在过去给了我稳定的结果。

这个数字需要定期更新,因为即使温度可以加速或减慢纳米计时器。

注意:将两台机器可靠地保持在一毫秒内是令人惊讶的。 ;)