Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8024036

Thread.sleep(long) is not immune to system time shifts with Linux kernel 3.7.10

XMLWordPrintable

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

            Unassigned Unassigned
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: