This question already has an answer here:
- How accurate is Thread.sleep? 3 answers
Thread.sleep(500) will suspends current thread for at least 500 milliseconds i know it may be little more than 500 but it never less than that. Now 1 millisecond=1000000 nanoseconds I want to suspend current thread for 500 milliseconds i.e.=500*1000000 nanoseconds But when i run the following code it sometimes sleep less than specified value in nanoseconds. Why is this? and how to sleep for at least 500*1000000 nanoseconds.
long t1=System.nanoTime();
try{
Thread.sleep(500);
}catch(InterruptedException e){}
long t2=System.nanoTime();
System.out.println((t2-t1)+" nanoseconds");
System.out.println((500*1000000-(t2-t1))+" nanoseconds");
sometimes Output is
499795328 nanoseconds
204672 nanoseconds
I'm not sure where you got that idea. The docs state quite clearly that it will sleep "for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers".
There is nothing guaranteeing that the duration is an absolute minimum.
If you want to get closer to the ideal, you already have half the solution since you're working out how many nanoseconds were left in the duration. To work out how many more milliseconds to sleep, you could divide the shortfall (204672 in this case) by a thousand then sleep again.
In fact, you'd probably want to do this in a loop until the remaining time reached zero. Something like the following pseudo-code might work:
Or you could simply accept the fact that close enough is good enough, given that your error seems to be about 0.04% (about 400 parts per million).
The API docs says that the time is
So the exact time that it will sleep for is not defined.
With that said, it would make sense that if the thread starts to sleep half way through a millisecond and then awakens at the beginning of the specified millisecond, then it could sleep for up to 1 less millisecond then desired.
If you require precise timing, then Thread.sleep is probably the wrong tool, in fact any garbage collected language is probably the wrong tool.
One way to run code on a more precise delay or period is to use a ScheduledExecutorService