这个问题是关于进行某种等待的库函数之间的关系,例如Thread.sleep(long)
,Object.wait(long)
,BlockingQueue.poll(long, TimeUnit)
以及System.nanoTime()
和System.currentTimeMillis()
返回的值。
据我所知,Java应用程序可以访问至少两个主要是独立的时钟:
System.currentTimeMillis()
,基本上是挂钟时间,这也意味着像 NTP 守护程序这样的用户和系统软件可能会随着时间的推移摆弄它时间,可能导致价值在任何方向和数量上跳跃。System.nanoTime()
保证单调且或多或少稳定增加,但可能因为不太合理的处理器时钟频率和节电机制造成的伪像而漂移。现在我明白像Thread.sleep()
之类的库函数需要依赖一些依赖于平台的接口来挂起一个线程,直到指定的时间量过去,但可以安全地假设这些函数测量的时间基于System.nanoTime()
?
我知道这些功能都不能保证比几毫秒更精确地测量时间,但我感兴趣的是很长时间(如小时)等待。即如果我拨打Thread.sleep(10 * 3600 * 1000)
,两个时钟之间测量的时间可能相差几分钟,但我认为其中一个时间将在请求的10个小时内的一小部分内。如果两个时钟中的任何一个是,我假设它是System.nanoTime()
使用的时钟。这些假设是否正确?
答案 0 :(得分:2)
不,假设Thread.sleep基于System.nanoTime是不安全的。
Java依赖于操作系统来执行线程调度,它无法控制操作系统的执行方式。
答案 1 :(得分:1)
在大多数情况下,存在于jdk 1.5之前的基于时间的API(Timer,Thread.sleep,wait(long))都使用基于毫秒的时间。在jdk 1.5+(java.util.concurrent。*)中添加的大多数并发工具都使用基于nano的时间。
但是,我不认为jvm可以保证这些行为,所以你当然不应该以某种方式依赖行为。