我正在研究计算机硬件,我们了解到使用硬件计时器可获得比软件延迟更准确的结果。我已经在汇编中写了1毫秒的软件延迟,我可以开始一个使用这个延迟重复每个毫秒的过程,并且计数器每100毫秒做一次其他事情,这种技术不如使用我的硬件计时器那么准确内置了我现在要使用的硬件。
所以我想知道用Java构建的时序有多精确?我们有System.currentTimeMillis
和Thread.sleep
这些可能不会使用硬件计时器,那么这些内置Java方法与硬件计时器相比有多准确?
答案 0 :(得分:11)
Thread.sleep()
不准确。不准确程度取决于底层操作系统及其计时器和调度程序。我经历过并行进行的垃圾收集会导致睡眠过度。
在进行“实时”模拟时,您必须纠正主循环以查找sleep
的不准确性。这可以通过计算唤醒的预期时间并将其与唤醒的实际时间进行比较并校正下一循环中的差异来完成。
如果您需要更好的性能,请查看Java Real-Time System specification。我自己没有用过,所以我无法提供更多细节。
答案 1 :(得分:3)
来自Java语言规范。
Thread.sleep导致当前正在执行的线程进入休眠状态 (暂时停止执行)指定的持续时间,但须遵守 系统定时器和调度程序的精度和准确性。线程 不会失去任何监视器的所有权,并恢复执行 将取决于调度和处理器的可用性 执行线程。
答案 2 :(得分:2)
我没有发现Thread.sleep是准确的。事实上,我发现它的睡眠时间似乎低于它的承诺。
配置为睡眠1毫秒时的结果:
********* Average elapsed time = 957 micro seconds
以下是我的测试:
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);
}