Windows 10上的Java Thread.sleep()在S3睡眠状态下停止
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Windows 10上的Java Thread.sleep()在S3睡眠状态下停止相关的知识,希望对你有一定的参考价值。
有一个桌面应用程序使用Thread.sleep()来实现长(几分钟或几小时)延迟。这个应用程序从Windows XP到(至少)Windows 7都运行良好。应用程序计算未来需要做多少事情,然后点击Thread.sleep(msToWait)。即使系统在等待期间恰好进入S3睡眠状态,这一直工作正常。
但是,从Windows 10开始,如果机器已经在S3中,则Thread.sleep()之后的代码不会“按时”执行。似乎机器开始执行代码“msToWait”加上机器进入S3的时间(现在不是100%肯定,但很可能)。
早期版本的Windows没有表现出这种行为; Thread.sleep()之后的代码等待了适当的时间,而不管睡眠状态如何。
测试已在当前的JVM 1.7上进行。
这是Windows 10的错误吗?这是一个JVM错误吗?有解决方法吗?
附加数据:
开发了测试程序和程序。程序是运行程序,使机器休眠约一分钟,然后唤醒机器并等待程序完成。
如果这个程序在JVM版本:25.40-b25的Windows 10(报告为8)上运行,则会失败:
C:UsersTesterDownloads>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.
这是测试程序:
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.");
}
}
我意识到我可以尝试各种其他方法来睡觉,但我认为,因为我经历并记录了这一点,我会在尝试其他事情之前在此发布。
附加信息:此故障似乎也出现在Windows 8中(但不是7或更早)。
ADDITION 4/4/2019
这个问题在bugs.java.com上可见,位于以下网址JDK-8221971。
有一些早期的bug与该bug相关联。来自linke JDK-8146730的评论错误:
17-04-2017有关此主题的任何新闻?
04-04-2019已被推迟。这是一个低优先级,复杂的问题,没有人积极分配给它。
这是预期的有效行为。 documentation非常明确,说明:
这些睡眠时间不能保证精确,因为它们受底层操作系统提供的设施限制。
和:
在任何情况下,您都不能假设调用
sleep
将在指定的时间段内暂停该线程。
它可能是Windows 10中的一个错误..即使在开始菜单中在地铁中完成的重要事情有时也无法及时从暂停状态唤醒(取决于你所有的防火墙或残疾,不足为奇)。我建议使用processhacker或一些sysinternals工具检查线程/进程的状态,并尝试提出一些解决方案。然后检查windows事件日志等。
或者只是做一些愚蠢的事情,比如用信号量替换睡眠,并在命令行中执行睡眠。
文档非常肯定imho它应该及时醒来,只是你不应该依赖它作为某些数据的输出计时器,播放音乐等,但是花费100倍的时间是有点不同。
以上是关于Windows 10上的Java Thread.sleep()在S3睡眠状态下停止的主要内容,如果未能解决你的问题,请参考以下文章
Windows 10上的Java Thread.sleep()在S3睡眠状态下停止