Friday, August 30, 2019

Java Thread.sleep() on Windows 10 stops in S3 sleep status

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.



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).



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



Testing has been on the current JVM 1.7.



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




ADDITIONAL DATA:



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.



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.


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.


This is the test program:



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.



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



ADDITION 4/4/2019



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




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




17-04-2017 Any news on this topic?



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


No comments:

Post a Comment

hard drive - Leaving bad sectors in unformatted partition?

Laptop was acting really weird, and copy and seek times were really slow, so I decided to scan the hard drive surface. I have a couple hundr...