Thread.sleep有多准确?
我正在学习计算机硬件,我们知道使用硬件计时器比软件延迟获得更准确的结果。 我已经写了1毫秒的软件延迟汇编,我可以开始一个进程,使用这个延迟重复每millisecod和计数器每100毫秒做一些事情,这种技术会比使用硬件定时器内置了我现在要使用的硬件。
所以我想知道Java内置的时序有多准确? 我们有System.currentTimeMillis
和Thread.sleep
,这些可能不使用硬件定时器,所以与硬件定时器相比,这些内置的Java方法有多精确?
Thread.sleep()
不准确。 如何不准确取决于底层操作系统及其定时器和调度程序。 我经历过并行的垃圾收集会导致过度的睡眠。
在进行“实时”模拟时,您必须纠正主循环中sleep
的不准确性。 这可以通过计算唤醒的预期时间并将其与唤醒的实际时间进行比较,并纠正下一个循环中的差异来完成。
如果您需要更好的性能,请查看Java 实时系统规范 。 我没有使用它自己,所以我不能提供进一步的细节。
来自Java语言规范。
Thread.sleep会导致当前正在执行的线程在指定的持续时间内进入hibernate状态(暂时停止执行),这取决于系统定时器和调度程序的精度和准确性。 线程不会丢失任何监视器的所有权,恢复执行将取决于调度和执行线程的处理器的可用性。
我没有findThread.sleep是准确的。 事实上,我发现它似乎睡得比它承诺的要less。
结果configuration为睡眠1毫秒时:
********* Average elapsed time = 957 micro seconds
以下是我的testing:
public static void main(String[] args) throws InterruptedException { List<Long> list = new ArrayList<Long>(); int i= 0; while(i <=100){ long authStartTime = System.nanoTime(); Thread.sleep(1); long elapsedTime = System.nanoTime() - authStartTime; System.out.println("*****"+elapsedTime/1000+ " mics"); list.add(elapsedTime); i++; } long sum=0; for(long l : list){ sum = sum + l; } System.out.println("********* Average elapsed time = "+sum/list.size()/1000+" micro seconds"); System.exit(0); }