当前位置: 首页 > 面试题库 >

System.nanoTime()完全没用吗?

劳英华
2023-03-14
问题内容

如博客文章《当心Java中的System.nanoTime()》所述,在x86系统上,Java的System.nanoTime()使用CPU专用计数器返回时间值。现在考虑以下情况,我用它来衡量通话时间:

long time1= System.nanoTime();
foo();
long time2 = System.nanoTime();
long timeSpent = time2-time1;

现在,在多核系统中,可能是在测量了time1之后,将该线程调度到了另一个计数器,该计数器的计数器小于以前的CPU的计数器。因此,我们可以在time2中获得一个小于time1的值。因此,我们将在timeSpent中得到一个负值。

考虑到这种情况,是不是System.nanotime到目前为止几乎没有用?

我知道更改系统时间不会影响纳米时间。那不是我上面描述的问题。问题在于,每个CPU自打开以来都会保留一个不同的计数器。与第一个CPU相比,该计数器在第二个CPU上可以更低。由于操作系统可以在获取time1之后将线程调度到第二个CPU,因此timeSpent的值可能不正确,甚至为负数。


问题答案:

从当时的Sun JDK在当时的操作系统上运行时的观点出发,该答案写于2011年。那是很久以前的事!列文托夫的答案提供了最新的观点。

该帖子是错误的,并且nanoTime很安全。Sun的实时与并发专家David Holmes对该博客的评论进行了链接。它说:

使用QueryPerformanceCounter / QueryPerformanceFrequency API实现System.nanoTime()。QPC使用的默认机制由硬件抽象层(HAL)确定。版本。例如,由于TSC无法在SMP系统中的不同处理器上同步的问题,Windows XP Service Pack 2更改为使用电源管理计时器(PMTimer)而不是处理器时间戳计数器(TSC)。会根据电源管理设置而变化(并因此而变化与经过时间的关系)。

因此,在Windows上,直到WinXP SP2之前,这都是一个问题,但现在不是。

我找不到涉及其他平台的第二部分(或更多部分),但是该文章的确包含了Linux已经以相同的方式遇到并解决了相同问题的说明,并带有指向clock_gettime(CLOCK_REALTIME)的常见问题的链接。,其中说:

在所有处理器/内核中,clock_gettime(CLOCK_REALTIME)是否一致?(是否重要?例如ppc,arm,x86,amd64,sparc)。
它应该或被认为是越野车。

但是,在x86 / x86_64上,可能会看到未同步或可变的频率TSC导致时间不一致。2.4内核确实没有针对此的保护措施,而早期的2.6内核在这里也不是很好。从2.6.18版开始,检测到此问题的逻辑更好,我们通常会退回到安全的时钟源。

ppc始终具有同步的时基,因此这不成问题。

因此,如果Holmes的链接可以被理解为暗示着nanoTime调用clock_gettime(CLOCK_REALTIME),那么从x86内核2.6.18开始,并且始终在PowerPC上,它是安全的(因为IBM和Motorola与Intel不同,实际上知道如何设计微处理器)。

遗憾的是,没有提到SPARC或Solaris。当然,我们不知道IBM JVM做什么。但是,现代Windows和Linux上的Sun JVM可以实现这一目标。

编辑:这个答案是基于它引用的来源。但是我仍然担心这实际上可能是完全错误的。一些最新的信息将非常有价值。我刚找到一个指向Linux时钟的四年更新文章的链接,这可能会有用。



 类似资料:
  • 问题内容: 我知道这是现在测量时间的首选方法 。第一个明显的原因是nanoTime()提供了更精确的时序,另一个原因是我读到后者受系统实时时钟调整的影响。“受到系统实时时钟的影响”是什么意思? 问题答案: 在这种情况下,我发现以下博客摘录很有用: 如果您对 测量绝对时间 感兴趣,请始终使用 。请注意,它的分辨率可能非常粗糙(尽管在绝对时期这很少有问题。) 如果您对 测量/计算经过时间 感兴趣,请始

  • 问题内容: Accuracy Vs. Precision 我想知道的是在更新对象在游戏中的位置时应该使用System.currentTimeMillis()还是System.nanoTime()?他们的运动变化与自上次通话以来经过的时间成正比,我想尽可能地精确。 我已经读到不同操作系统之间存在一些严重的时间分辨率问题(即Mac / Linux的分辨率几乎为1毫秒,而Windows的分辨率为50毫秒

  • 我知道那套系统。nanoTime()现在是测量。第一个明显的原因是nanoTime()提供了更精确的计时,另一个原因是我读到的,后者受到系统实时时钟调整的影响。“受到系统实时时钟的影响”是什么意思?

  • 问题内容: 我正在构建一个类似于聊天的应用程序,该应用程序使用滚动视图将用户输入的文本显示在屏幕上。我正在做的是随着更多文本追加到屏幕上而自动向下滚动滚动视图。我正在使用 尽管出于某些原因,这似乎可行,因为在聊天时键盘通常位于屏幕上,因此当滚动视图向下滚动时,键盘并不能完全显示- 添加的最新文本视图不会显示(您必须手动向下滚动至最新视图之一)。我该如何解决这个问题? 问题答案: 我环顾四周,发现其

  • 投了两个月,终于被比亚迪捞起来面试了,早上九点跟我打电话说方不方便面试,我说不方便,然后推到了下午两点。 然后下午两点就是另一个人打电话了,因为上午的是惠州的电话,下午的是深圳的电话,而且一个是男的,一个是女的,所以很明显是两个人。 就在面完深圳那个之后,我写这个面经的时候,我又接到了上午那个惠州的电话。 我这是同一天被迪子捞了两次吗? 说说问题吧 先是深圳的那个,开头就问我想要去嵌入式软开还是全

  • 我想创建一个完全不使用任何XMLs的Spring应用程序(不web.xml不context.xml或任何东西)。到目前为止,它似乎工作得很好,除了我的视图解析器有一些问题,我不能自己解决。 这是我的WebApplicationInitializer 还有我的spring配置 最后是我的控制器 位于。 因此,如果我在控制器中使用注释,那么控制器会给我响应“index”,因此我知道我的配置至少在某种程