JDK-8024036 : Thread.sleep(long) is not immune to system time shifts with Linux kernel 3.7.10
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 7u11,7u25,7u40
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • Submitted: 2013-08-29
  • Updated: 2013-09-12
  • Resolved: 2013-09-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9Resolved
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
I found different java versions that are affected:
java version "1.7.0_11"
Java(TM) SE Runtime Environment (build 1.7.0_11-b21)
Java HotSpot(TM) 64-Bit Server VM (build 23.6-b04, mixed mode)

java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)

java version "1.7.0_40"
OpenJDK Runtime Environment (IcedTea 2.4.1) (suse-8.18.1-x86_64)
OpenJDK 64-Bit Server VM (build 24.0-b50, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux xxx.xxx.xxx 3.7.10-1.16-default #1 SMP Fri May 31 20:21:23 UTC 2013 (97c14ba) x86_64 x86_64 x86_64 GNU/Linux

openSuSE 12.3

A DESCRIPTION OF THE PROBLEM :
- System time is 10:00:00 UTC.
- Start Thread.sleep(TimeUnit.MINUTES.toMillis(5))
- Change system time to 9:50:00 UTC
=> Thread.sleep(TimeUnit.MINUTES.toMillis(5)) returns at 10:05:00 UTC and not on 9:55:00 UTC.

The problem does not exist with older kernels.
I have tested
Linux xxx 2.6.31.14-0.8-default #1 SMP 2011-04-06 18:09:24 +0200 x86_64 x86_64 x86_64 GNU/Linux


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the attached test case, e.g. java SleepTest 1. It prints out the current system time once a second
2. Modify the system time backwards, e.g.
# date
Thu Aug 29 11:00:00 UTC 2013
# date +%T -s "10:50:00"
# date
Thu Aug 29 10:50:01 UTC 2013



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The output of the SleepTest program should continue printing out the new system time (10:50:xx) once a second after the system time has been modified.


Expected output:
10:59:57
10:59:58
10:59:59
11:00:00
10:50:00
10:50:01
...
ACTUAL -
The SleepTest program stops until the system time has reached the old time before the time change. It continues not until system time has reached 11:00:01 again.

Actual output:
10:59:57
10:59:58
10:59:59
11:00:00
11:00:01
11:00:02

(program does not output anything for 10 minutes between 11:00:00 and 11:00:01)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;

public class SleepTest
{
    private TimeZone defaultTimeZone = null;
    private final String TIME_FORMAT = " HH:mm:ss ";
    private SimpleDateFormat timeFormat = null;

    SleepTest(int seconds)
    {
        this.defaultTimeZone = TimeZone.getDefault();

        this.timeFormat = new SimpleDateFormat(this.TIME_FORMAT);
        this.timeFormat.setTimeZone(this.defaultTimeZone);

        System.out.println("interval: " + seconds + " seconds");
        System.out.println(Calendar.getInstance(this.defaultTimeZone).getTime());

        for (;;)
        {
            try
            {
                Thread.sleep(seconds * 1000);
                System.out.println(Calendar.getInstance(this.defaultTimeZone).getTime());
            }
            catch (Exception e)
            {
                System.out.println(Calendar.getInstance(this.defaultTimeZone).getTime());
                System.out.println(e);
            }
        }
    }

    public static void main(String[] args)
    {
        int seconds = 1;
        if (args.length > 0)
        {
            seconds = Integer.valueOf(args[0]);
        }

        new SleepTest(seconds);

        try
        {
            Thread.sleep(1000000000);
        }
        catch (Exception e)
        {
        }
    }
}

---------- END SOURCE ----------
Comments
Please close as a dup of 6900441.
04-09-2013

This is a duplicate of 6900441. Though it is unclear why the problem is only being seen in these more recent kernels.
01-09-2013

SQE is ok to defer to JDK9
30-08-2013

Dev: request deferral to JDK 9 where we are planning to address the time issues
30-08-2013