Windows上的Java准确睡眠

HaB*_*LeS 21 java windows sleep

有没有人知道为Java提供Thread.sleep()的库,其错误不高于1-2毫秒?

我尝试了Sleep,错误测量和BusyWait的混合,但我不能在不同的Windows机器上获得这种可靠性.

如果该实现也适用于Linux和MacOS,它可以是本机实现.

编辑 Nick提供的链接(http://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks)是一个非常好的资源,可以理解java所有类型的计时器/睡眠/时钟的问题.

Poo*_*ool 17

要提高睡眠粒度,可以在此Thread.sleep页面中尝试以下操作.

在Windows下使用Thread.sleep()的错误

如果时间对于您的应用程序至关重要,那么绕过这些错误的一种不优雅但实用的方法是在应用程序的整个持续时间内运行一个守护程序线程,它只能睡眠很长的素数毫秒(Long.MAX_VALUE会这样做).这样,中断周期将根据您的应用程序的调用来设置一次,最大限度地减少对系统时钟的影响,睡眠粒度设置到1毫秒甚至在默认中断期间不为15ms.

该页面还提到它会导致系统范围内的Windows更改,这可能导致用户的时钟由于此错误而快速运行.

编辑

有关此内容的更多信息,请参阅此处以及Sun 提供 的相关错误报告.

  • 这有很大帮助.我在两台不同负载的Windows机器上运行测试,平均误差为0.8ms.在Linux上我的平均误差为0.3ms - Thanx你节省了我的一天:-) (2认同)

Joa*_*lva 11

这已经晚了5个月,但对于阅读这个问题的人来说可能会有用.我发现,java.util.concurrent.locks.LockSupport.parkNanos()做同样的Thread.sleep(),但以纳秒精度(理论上),和更好的精度比Thread.sleep()在实践中.这当然取决于你正在使用的Java Runtime,所以YMMV.

看看:LockSupport.parkNanos

(我在Sun的1.6.0_16-b01 VM for Linux上验证了这一点)

  • 我刚刚试过这个,它不会停顿少于1毫秒,这和Thread.sleep是一样的。:( (2认同)

And*_*kov 8

不幸的是,从Java 6开始,Windows OS上的所有与Java睡眠相关的方法[包括LockSupport.awaitNanos()]都基于毫秒,如上面几个人所提到的.

计算精确间隔的一种方法是"旋转屈服".方法System.nanoTime()为您提供相当精确的相对时间计数器.这次通话的费用取决于你的硬件,大约是2000-50纳米.

这是Thread.sleep()的替代建议:

   public static void sleepNanos (long nanoDuration) throws InterruptedException {
        final long end = System.nanoTime() + nanoDuration;
        long timeLeft = nanoDuration;
        do {
            if (timeLeft > SLEEP_PRECISION)
                Thread.sleep (1);
            else
                if (timeLeft > SPIN_YIELD_PRECISION)
                    Thread.yield();

            timeLeft = end - System.nanoTime();
        } while (timeLeft > 0);
    }
Run Code Online (Sandbox Code Playgroud)

这种方法有一个缺点 - 在等待命中CPU核心的最后2-3毫秒.请注意,sleep()/ yield()将与其他线程/进程共享.如果你愿意妥协一点CPU,这会给你非常准确的睡眠.

  • 你如何计算SPIN_YIELD_PRECISION?它只有1毫秒? (2认同)