I’m pretty
sure, you know java.lang.Thread class and it’s API. Today I want to spend some
time with sleep method. void sleep (long
millis) is pretty straight – just remember not to set negative value and be
ready for InterruptedException, that’s it.
But what if you need better precision? Great, there is another sleep method, this time with two arguments – millis and nanos.
The Javadoc
is clear:
Causes the currently executing thread to sleep
(temporarily cease execution) for the specified number of milliseconds, subject
to the precision and accuracy of system timers and schedulers.
See? You can set some amount of nanoseconds to the
Thread to sleep, but the precision is dictated by system timers and
schedulers. Okay computers are fast
these days, so the precision wouldn’t be so bad.
You start to use it, but the results are far
from what you expected. Double check your code, everything looks good. Okay it
is time to see the source code.
WTF. WTF? WTF!
Here is the code (jdk1.7.0_10):
public static void sleep(long millis, int nanos)
throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
millis++;
}
sleep(millis);
}
See something you don’t like?
First, you see that it calls sleep(millis),
so it always sleep the thread to at least one millisecond! Where is my
nanosecond precision?
Than you see the if statement and another WTFs are on its way.
It just rounds the value to milliseconds and
when there is some amount of nanos and 0 value of millis, it just sets millis value to 1 to be sure, there is some sleep happening.
I’m sorry, but I can’t see any timers or
schedulers involved.
I wanted to thank the author, but the author is
“unascribed” – maybe that explains it.