Windows 10上的Java Thread.sleep()在S3睡眠状态下停止

有一个桌面应用程序使用Thread.sleep()来实现长时间(几分钟或几小时)的延迟。 这个相同的应用程序通过(至less)Windows 7从Windows XP工作正常。应用程序计算将来需要做多less事情,然后命中Thread.sleep(msToWait)。 即使系统在等待期间碰巧进入S3睡眠状态,这一直工作正常。

从Windows 10开始,Thread.sleep()之后的代码如果机器已经在S3中,则不会“按时”执行。 看来,机器开始执行代码在“msToWait”加上机器已经在S3的时间(现在不是100%确定,但可能)。

早期版本的Windows没有performance出这种行为; Thread.sleep()之后的代码等待适当的时间,不pipe睡眠状态如何。

testing已经在当前的JVM 1.7上。

这是一个Windows 10的错误? 这是一个JVM的错误? 有没有解决办法?

其他数据:

开发了testing程序和程序。 程序是运行程序,使机器hibernate大约一分钟,然后唤醒机器并等待程序结束。

如果这个程序在Windows 10(报告为8)上运行,并且JVM版本为:25.40-b25,则失败:

C:\Users\Tester\Downloads>SleepTester.exe Wed Apr 01 10:47:35 PDT 2015 Using default number of minutes: 5 Wed Apr 01 10:47:35 PDT 2015 You can use "SleepTester -minutes 10" to have it sleep for 10 minutes, for example. Wed Apr 01 10:47:35 PDT 2015 JVM Version: 25.40-b25 Windows Version: Windows 8 Wed Apr 01 10:47:35 PDT 2015 The program will now wait for 5 minutes. Expect wrap-up at Wed Apr 01 10:52:35 PDT 2015 Wed Apr 01 10:53:38 PDT 2015 The system has come through the Thread.sleep(300000). Wed Apr 01 10:53:38 PDT 2015 This should be a low number: 63589 Wed Apr 01 10:53:38 PDT 2015 This appears to be operating incorrectly...the expected sleep time has NOT been achieved. Wed Apr 01 10:53:38 PDT 2015 Program is ending. 

如果该进程在Windows 7上运行,则不会失败。

 Wed Apr 01 17:12:18 EDT 2015 Java Runtime Version: 1.8.0_31-b13 JVM Version: 25.31-b07 Windows Version: Windows 7 Wed Apr 01 17:12:18 EDT 2015 The program will now wait for 6 minutes. Expect wrap-up at Wed Apr 01 17:18:18 EDT 2015 Wed Apr 01 17:18:18 EDT 2015 The system has come through the Thread.sleep(360000). Wed Apr 01 17:18:18 EDT 2015 This should be a low number: 0 Wed Apr 01 17:18:18 EDT 2015 Program is ending. 

这是testing程序:

 import java.util.Date; public class SleepTester { private static int mMinutes; private static int mDefault = 5; public static void main(String[] args) throws Exception { for (int iArg = 0; iArg < args.length; ++iArg) { if (args[iArg].equals("-minutes") && (iArg + 1) < args.length) { mMinutes = Integer.parseInt(args[++iArg]); } } if (mMinutes == 0) { mMinutes = mDefault; System.out.println(new Date() + " Using default number of minutes: " + mDefault); System.out.println(new Date() + " You can use \"SleepTester -minutes 10\" to have it sleep for 10 minutes, for example."); } System.out.println(new Date() + " Java Runtime Version: " + System.getProperty("java.runtime.version") + " JVM Version: " + System.getProperty("java.vm.version") + " Windows Version: " + System.getProperty("os.name")); long msDelay = mMinutes * 60 * 1000; long wakePoint = new Date().getTime() + msDelay; System.out.println(new Date() + " The program will now wait for " + mMinutes + " minutes. Expect wrap-up at " + new Date(wakePoint)); Thread.sleep(msDelay); // If the machine goes into S3 during this interval, it should not matter, as long as it's awake when it fires. System.out.println(new Date() + " The system has come through the Thread.sleep(" + msDelay + "). "); long msAccuracy = Math.abs(new Date().getTime() - wakePoint); System.out.println(new Date() + " This should be a low number: " + msAccuracy); if (msAccuracy > 1000) System.out.println(new Date() + " This appears to be operating incorrectly...the expected sleep time has NOT been achieved."); System.out.println(new Date() + " Program is ending."); } } 

我意识到我可以尝试各种其他方法来睡觉,但我认为,因为我经历和logging这一点,我会在尝试其他事情之前张贴在这里。

附加信息:这种失败似乎也出现在Windows 8(但不是7或以前)。

Solutions Collecting From Web of "Windows 10上的Java Thread.sleep()在S3睡眠状态下停止"

这可能是Windows 10中的一个错误。即使是像开始菜单那样在地铁中完成的至关重要的事情,有时也无法及时从暂停状态中唤醒(具体取决于您所有防火墙或禁用的内容,足够意外)。 我会建议用processhacker或一些sysinternals工具检查线程/进程的状态,并尝试提出一些解决方案。 然后检查与Windows事件日志等。

或者只是做一些愚蠢的事情,例如用信号量代替睡眠,并在命令行中执行睡眠。

文件是非常确定的,它应该及时醒来,只是你不应该依靠它作为一些datalines输出计时器,播放音乐或类似的,但采取100倍的时间有点不同。

这是预期的,有效的行为。 该文件非常明确,指出:

这些睡眠时间并不能保证是精确的,因为它们受底层操作系统提供的设施的限制。

和:

在任何情况下,您都不能假定调用sleep会在指定的时间段内暂停该线程。