Windows 10上的Java Thread.sleep()在S3睡眠状态下停止 [英] Java Thread.sleep() on Windows 10 stops in S3 sleep status

查看:266
本文介绍了Windows 10上的Java Thread.sleep()在S3睡眠状态下停止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个桌面应用程序使用Thread.sleep()来实现长时间(数分钟或数小时)的延迟.从Windows XP到(至少)Windows 7,该应用程序都可以正常工作.该应用程序将计算将来需要执行的操作,然后单击Thread.sleep(msToWait).即使系统在等待期间碰巧进入了S3睡眠状态,也可以正常工作.

There's a desktop application that uses Thread.sleep() to achieve long (minutes or hours) delays. This same application has been working fine from Windows XP through (at least) Windows 7. The application calculates how far in the future it needs to do something, then hits a Thread.sleep(msToWait). This has been working fine, even if the system happens to go into S3 sleep state during the wait.

但是,从Windows 10开始,如果机器位于S3中,则Thread.sleep()之后的代码不会按时"执行.看来机器开始在"msToWait"处加上机器进入S3的时间开始执行代码(目前尚不能百分百确定,但有可能).

As of Windows 10, though, the code after Thread.sleep() does not execute "on time" if the machine has been in S3. It appears that the machine begins executing code at "msToWait" plus the time the machine has been in S3 (not 100% sure of this right now, but likely).

Windows的早期版本没有出现此现象;不论睡眠状态如何,Thread.sleep()等待正确的时间后,代码都会保持不变.

Earlier versions of Windows did not exhibit this behavior; code after Thread.sleep() waited the right amount of time, irrespective of sleep status.

已经在当前的JVM 1.7上进行了测试.

Testing has been on the current JVM 1.7.

这是Windows 10的错误吗?这是JVM错误吗?有解决方法吗?

Is this a Windows 10 bug? Is this a JVM bug? Is there a work-around?

其他数据:

制定了测试程序和程序.步骤是运行程序,使机器休眠约一分钟,然后唤醒机器并等待程序完成.

A test program and procedure were developed. The procedure is to run the program, cause the machine to sleep for about a minute, then wake the machine and wait for the program to finish.

如果此程序在具有JVM版本:25.40-b25的Windows 10(报告为8)上运行,则它将失败:

If this the program is run on Windows 10 (reporting as 8) with JVM Version: 25.40-b25, it fails:

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上运行,则不会失败.

If the process is run on Windows 7, it does not fail.

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.");
}
}

我意识到我可以尝试其他各种睡眠方法,但是我认为,自从我进行了记录并记录下来之后,我便将其张贴在这里,然后再尝试其他方法.

I realize I could try various other methods to sleep, but I thought that since I went through and documented this, I'd post it here before trying other things.

其他信息:此故障似乎也出现在Windows 8(但不是7或更早版本)中.

Additional Information: This failure seems also to appear in Windows 8 (but not 7 or prior).

该问题在bugs.java.com的以下URL上可见: JDK-8221971 .

The issue is visible on bugs.java.com at the following url JDK-8221971.

与该错误相关的还有一些较早的错误.链接JDK-8146730错误的评论:

There are a few earlier bugs linked to that bug. A comment from the linke JDK-8146730 bug:

2017年4月17日有关此主题的任何新闻?

17-04-2017 Any news on this topic?

04-04-2019已推迟.它的优先级较低,而且很复杂,因此没有人被主动分配给它.

04-04-2019 It has been deferred. It is a low priority, and complex, issue no one is actively assigned to it.

推荐答案

这是预期的有效行为. 文档非常明确,指出:

This is expected, valid behavior. The documentation is very explicit, stating:

这些睡眠时间不受精确操作系统的限制,因为它们受底层操作系统提供的功能的限制.

these sleep times are not guaranteed to be precise, because they are limited by the facilities provided by the underlying OS.

和:

无论如何,您不能假定调用sleep将在指定的时间段内精确地挂起线程.

In any case, you cannot assume that invoking sleep will suspend the thread for precisely the time period specified.

这篇关于Windows 10上的Java Thread.sleep()在S3睡眠状态下停止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆