Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4500388
Votes 5
Synopsis Calling Thread.sleep with small argument affects system clock on windows
Category java:runtime
Reported Against 1.3 , 1.4 , 1.3.1 , 1.4.1 , 1.3.1_04
Release Fixed 1.3.1_04
State 10-Fix Delivered, bug
Priority: 4-Low
Related Bugs 4712392 , 4717583 , 4814012 , 4881604 , 5005837
Submit Date 06-SEP-2001
Description
Multithreading timers less than 10 ms causes Windows clock to run too fast.Compile the test case on JDK 1.3.0 and run on Windows 2000 Professional,Use an independent timer (like a kitchen timer) to measure the execution time of the program.

The 5 ms sleep causes a call to NTSetTimerResolution in the OS to set the timer to 1 ms resolution (in order to discriminate the passage of 5 ms).
 The multithreading of the timers is causing a problem.
 
 The problem is not observed in classic mode, or using the MS virtual machine.

 TESTCASEBEGIN
 /**
  * This class is meant to demonstrate an issue with the system time when 
running the HotSpot VM and sleeping for less than 10 ms. When it is run with the HotSpot VM, the system time will be off. The program will run for 10 system minutes, but when verifying with a stop watch, is took only 9 minutes and 50 seconds.
  * Steps to try this:
  * 1. Set a count-down timer to 10 minutes.
  * 2. At the same moment, run the application and start the count-down timer.
  * 3. At the moment the software stops, stop the timer. When the timer is 
       zero,it means that the system took 10 real minutes. When there is time           left on the timer, the system took less than 10 minutes.
+  * Another way to try this:
+  * 1. Remove the code where the "timer" is created so the application
+  *    will not stop after 10 minutes.
+  * 2. Set an external clock at exactly the same time as the computer clock.
+  * 3. Run the application.
+  * 4. After a couple of hours, compare the system clock with the external 
        clock.
+ Note that the system clock is a couple of minutes fast.
   */


 public class TestBase {
    public int launchThread(final int id, final int sleepTime) {
 
       // Create a new thread object
       Thread t = new Thread(new Runnable() {
                                public void run() {
                                   // Loop forever
                                   while (true) {
                                      // Print the ID
                                      System.out.print(""+id);
                                      // Do some processing
                                      for (int i=0; i<1000; i++) {
                                         for (int j=0; j<1000; j++) {
                            double x = (double)i * j / j + i - j * j;
                                        }
                                      }
               // Sleep for the amount specified in the sleep time
                                     
   try {
	Thread.currentThread().sleep(sleepTime);
                 }
                    catch (InterruptedException e) {
                                         ;
                                      }
                                   }
                                }
                             });
       // Start the thread
       t.start();
       return 0;
    }
 
    public static void main(String[] args) {
       // Create a Thread that will print the ms time every 30 seconds
       Thread timer = new Thread(new Runnable() {
                                    public void run() {
                                       // Print the begin time
                                       long start = System.currentTimeMillis();
                      System.out.println("Start time: " + start);
                                       try {
                                          // Sleep for 10 minutes
                                          Thread.currentThread().sleep(600000);
                                       }
                                       catch (InterruptedException e) {
                                          ;
                                       }
                                       // Print the current time
                  System.out.println("time: " +(System.currentTimeMillis() - start));
                                       System.exit(0);
                                    }
                                 });
       // Start the timer thread
       // Remove this line of code when it is not desired to stop the app after 10 minutes.
       timer.start();
 
       // Create a new test base object
       TestBase tb = new TestBase();
 
       // Launch a thread with a 5 ms sleep time
       tb.launchThread(1, 5);
 
       // Launch a thread with a 10 ms sleep time
       tb.launchThread(2, 10);
    }
 }
 
 
 
 
 
 TESTCASEEND
Work Around
None
Evaluation
Hotspot uses Windows routines timeBeginPeriod() and timeEndPeriod() to change the Windows timing resolution from its default value to one millisecond and back during a Thread.sleep(). Frequently changing the resolution appears to be causing errors in Windows time keeping (speculation).  Simply avoiding timeBeginPeriod use would cause errors in timing short delays less than 10ms. 

Here's similar analysis and a suggested solution from Ken Russell:

"I don't recommend removing the timeBeginPeriod()/timeEndPeriod() calls
because that will prevent sleeps from under 10 ms from working properly. If
this is a critical customer issue then one solution would be to provide a
product-mode flag which would disable the effect of the
HighResolutionInterval class and also set the time interval to 1 ms when the
VM starts up, incurring a performance penalty but maintaining correctness. I
assume the skew is caused by the multiple calls to
timeBeginPeriod()/timeEndPeriod() and not simply by the increasing of the
resolution of the timer." (from 8/18/2001 email).

 xxxxx@xxxxx  2001-09-18

I ran the test case on an NT 4.0/SP4 system and it ran in 10 minutes two seconds. On a W98/SE system it ran in 10 minutes one second.

 xxxxx@xxxxx  2001-09-18
Comments
  
  Include a link with my name & email   

Submitted On 10-OCT-2001
rraykov
I am experiencing this behavior not only when using sleep 
with small arguments, but rather big ones too, like 40000 
ms for example. The same behavior appears even when the 
thread is blocked by invoking wait() on it and is doing 
nothing. The system clock gains about 10 sec every minute, 
no matter whether the thread is waking up every minute and 
going back to sleep for another minute, or it is 
permanently blocked and waiting for another process to wake 
it up. This behavior does definitely not appear in Linux or 
Windows NT and does definitely appear in Windows 2000.

Rumen


Submitted On 14-MAR-2002
manu4ever
This isn't specific to sleeps of under 10ms. A sleep that isn't an exact multiple of 10ms will have the same 
effect. From the 1.3 SCSL code for hotspot, the constructor/destructor of class HighResolutionInterval 
calculate <sleep duration>%10 and call timeBeginPeriod/timeEndPeriod if the mod isn't zero. We had exactly 
this problem with an app that did a lot of Thread.sleep(15). Changing it to Thread.sleep(20) fixed it.


Submitted On 27-SEP-2002
bkolloju
I agree with manu4ever. I have also experienced similar 
behaviour, the system clock runs faster when a Thread.sleep
(with a time duration of non-multiple of 10)is used in between 
two System.currentTimeMills() call. 

One workaround is to use Object.wait() inplaceof Thread.sleep
(). Wait doesn't have any effect of time shift.


Submitted On 25-NOV-2002
nis@pfu
Some computer can reproduce this problem with 1.3.1_04 or
1.3.1_06.
Are you sure you fixed this?


Submitted On 06-DEC-2002
xpetos
It seems that the fix for this breaks sleeps with even 10 ms 
multiples on a dual cpu machine. A sleep(10) on JDK
1.2.2_011 on W2K is OK (7% error in time). On 1.3 (and on)
it gives 56% error. The fix does not take into account that
the timer resolution on a 2 CPU machine is 15625000 ns.


Submitted On 04-MAR-2003
Delisarl
The bug is NOTclosed in my opinion,
the flag -XX:+ForceTimeHighResolution (see related bug 
4814012 for details) is only a workaround and must be more 
documented here !!!
With jdk/jre 1.4.1 the bug is confirmed on Windows 2000 SP3 
(and NOT before) and Windows XP SP1 (not checked without 
SP1)


Submitted On 15-APR-2004
ceckt
Many Pentium4 computers reproduce this problem 
with JDK1.3.1_10 and JDK1.4.2.
Pentium2/3 computers arenot reproduce.
Is this problem depends hardware?


Submitted On 21-APR-2004
Markus-Kuhn
A Java program which calls in a loop first sleep with 
9ms and then with 10ms causes the system clock to 
run on our computer at double speed.
The problem only occures if the HAL 'halaacpi'  
or 'halmacpi' is used.
Depending on the hardware, the clock runs too fast 
with the following factors : 2   1.6  1.04
For further information on the behaviour see also the 
following Microsoft page:
http://support.microsoft.com/?id=821893 


Submitted On 04-AUG-2004
Denis.Tsyplakov
Bug stil exists in 1.4.2_00
Where is cure?


Submitted On 22-FEB-2006
0xfade0ff
The bug does still exist in JRE5.0.


Submitted On 02-MAY-2006
i_program_java_all_day
Please re-open this bug, this is still occurring on certain windows hardware such as hp-compaq D530 SFF pentium 4.  Reproduced using JRE 1.4.2_06 and _08.


Submitted On 28-AUG-2006
davidholmes
See also 6435126 (the see also list above has been truncated)

Please add all further comments to either 6435126 or 5005837.




PLEASE NOTE: JDK6 is formerly known as Project Mustang