我目前正在用Java编写多线程程序。在某些时候,不同的线程会记录其操作,而我为此使用 nanoTime
。每个线程都有其自己的日志文件,最后我将它们合并,并根据它们的时间(nanoTime
)对它们进行排序,以查看发生了什么。问题是我有类似的错误行为,其中x
是 volatile
变量:
// logged by thead1
x = true // done at time 0000, time computed & logged after x = true was done
// no events in between
// logged by thread2
read x // reads false while time before reading is 0001
所以在我看来,
nanoTime
并没有真正正确地计时事情。在
nanoTime
文档中,它写为:由同一个进程创建的线程是否有可能在不同的JVM中执行?这可以解释
nanoTime
的错误行为,但仍然没有太大意义。有任何想法吗? 最佳答案
这完全取决于操作系统,但是如果您有一个CPU插槽,则使用nanoTime看到任何错误都将很困难。如果使用Wiindows 7+或Linux的最新版本,nanoTime会纠正套接字之间的差异。顺便说一句,如果您有一个多插槽XP盒子,您可以看到nanoTime来回跳动了几毫秒。 (简而言之,不要在多插槽计算机上使用XP并期待良好的结果)
另请注意,某些操作系统仅具有微秒级的分辨率。这意味着您可以在线程之间执行许多操作,并且所有这些操作似乎都具有相同的时间戳。解决方案是使用具有更高分辨率计时器的OS。这不涉及更改代码甚至JVM。
我不知道有什么办法可以做到这一点,也没有想到这很重要的原因。无论您使用哪个线程,JVM或进程,都将进行相同的系统调用。
很可能您的操作系统上的调用nanoTime()调用只有微秒级的分辨率。
如果您的时间比微秒更好,那么对nanoTime()的每次调用都可能会有所不同。通过缓存更新易失变量至少需要75个时钟周期或〜20纳秒。没有什么是即时的,我发现线程之间的延迟对于线程之间的微不足道的更新接近100纳秒。
关于java - Java nanoTime的多线程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20083072/