JDK-4365109 : (thread) Thread.sleep() sleeps more than required on dualprocessor
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.2.0
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_nt
  • CPU: x86
  • Submitted: 2000-08-23
  • Updated: 2005-08-17
  • Resolved: 2005-08-17
Related Reports
Relates :  
Relates :  
Description
Name: stC104175			Date: 08/23/2000


java version "1.2.2"
Classic VM (build JDK-1.2.2-W, native threads, symcjit)

When using Thread.sleep(), I have a delay problem using jdk 1.2
on a dual processor win 4.0 server nt machine (NetFinity).
I don't have this problem on a single processor machine.

I reproduced the problem with the following test code.

class tClock {
    public static void main(String[] args) {

        Thread t = new Sleeper();
                        
        t.start();

    }
}

class Sleeper extends Thread {
    public void run() {
	try {
	    Timestamp currentDate = new Timestamp( System.currentTimeMillis() );
	    System.out.println("Starting at " + currentDate);

	    long timeToSleep = 1; //minutes
	    timeToSleep *= ((long)(60 * 1000));
	    System.out.println("Next time to wake up: (" + timeToSleep + "): "
			       + new Timestamp( System.currentTimeMillis()
                               + timeToSleep ));
	    sleep(timeToSleep);
	    
	    System.out.println("Sleeper woke up at:         "
			       + new Timestamp( System.currentTimeMillis() ));
	    yield();
	    
	    timeToSleep = 60; //minutes
	    timeToSleep *= ((long)(60 * 1000));
	    System.out.println("Next time to wake up(" + timeToSleep + "): "
			       + new Timestamp( System.currentTimeMillis() +
timeToSleep ));
	    sleep(timeToSleep);
	    
	    System.out.println("Sleeper woke up at           : "
			       + new Timestamp( System.currentTimeMillis() ));
	    yield();

	    timeToSleep = 120; //minutes
	    timeToSleep *= ((long)(60 * 1000));
	    System.out.println("Next time to wake up(" + timeToSleep + "): "
			       + new Timestamp( System.currentTimeMillis() +
timeToSleep ));
	    sleep(timeToSleep);
	    
	    System.out.println("Sleeper woke up at           : "
			       + new Timestamp( System.currentTimeMillis() ));
	    yield();

	    timeToSleep = 180; //minutes
	    timeToSleep *= ((long)(60 * 1000));
	    System.out.println("Next time to wake up(" + timeToSleep + "): "
			       + new Timestamp( System.currentTimeMillis() +
timeToSleep ));
	    sleep(timeToSleep);
	    
	    System.out.println("Sleeper woke up at            : "
			       + new Timestamp( System.currentTimeMillis() ));
	    yield();
	} catch (InterruptedException e) {
                System.out.println("sleeper interrupted (1): "
				   + isInterrupted());
                System.out.println("sleeper interrupted");
	}
	System.out.println("sleeper interrupted (2): " + isInterrupted());
    }
}

The results are the following:

Starting at 2000-05-17 10:28:30.968
Next time to wake up(60000): 2000-05-17 10:29:31.031
Sleeper woke up at         : 2000-05-17 10:29:31.031
Next time to wake up(3600000): 2000-05-17 11:29:31.031
Sleeper woke up at           : 2000-05-17 11:30:47.031
Next time to wake up(7200000): 2000-05-17 13:30:47.031
Sleeper woke up at           : 2000-05-17 13:39:32.046
Next time to wake up(10800000): 2000-05-17 16:39:32.046
Sleeper woke up at            : 2000-05-17 16:52:18.046
sleeper interrupted (2): false
(Review ID: 106603) 
======================================================================

Comments
EVALUATION The test case is demonstrating the effects of OS context switching overhead. For whatever reason, the OS is having to fault a lot of pages back in (and probably doing other work too) to get the long-delayed thread resumed after the sleep. Trying to "fix" this in Java would hurt the performance of other applications, since the OS presumably reused the resources used by the sleeping thread for a purpose. See section 17.9 of the JLS at http://java.sun.com/docs/books/jls/third_edition/html/memory.html for the formal version of the limits imposed on Thread.sleep.
17-08-2005