3

I was checking out the Java 8 standard library source code just out of curiosity, and found this in java/lang/Object.java. There are three methods named wait:

  • public final native void wait(long timeout): This is the core of all wait methods, which has a native implementation.
  • public final void wait(): Just calls wait(0).
  • And then there is public final void wait(long timeout, int nanos).

The JavaDoc for the particular method tells me:

This method is similar to the wait method of one argument, but it allows finer control over the amount of time to wait for a notification before giving up. The amount of real time, measured in nanoseconds, is given by:

1000000*timeout+nanos

But this is how the method achieves "finer control over the amount of time to wait":

if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
    timeout++;
}

wait(timeout);

So this method basically does a crude rounding of nanoseconds to milliseconds. Not to mention that anything below 0.5ms will still be rounded up to 1ms.

Is this piece of code bad/unnecessary, or am I missing some unseen virtue of declaring this method, and its no argument cousin as the way they are?

  • 8
    it allows other JVMs to implement it any way they choose where µs accuracy can be achieved – ratchet freak Aug 12 '14 at 12:10
  • @ratchetfreak why not provide this as an answer and maybe add an example for one such JVM? – Frank Aug 12 '14 at 13:12
  • Nanos below 0 aren't ignored if timeout is zero, so you get a timeout of 1 if you specify timeout 0 nanos 1. – Sign Aug 12 '14 at 13:17
  • I think this is due to the fact that not all operating systems expose nanosecond accuracy at the API level. So certain Oracle implementations might fudge it a little. In my own experience I have found nanos to be unreliable. I have actually added nano timing in code where millisecond intervals returned zero, and have received negative time intervals. So something in the implementation is a bit wonky. – user22815 Aug 12 '14 at 15:04
  • 1
    Interestingly, the wait() method on Linux is probably done by using pthread_cond_timedwait(), which already has nanosecond timeouts natively. Of course, it's a good question whether you can expect to be able to wait only 1 nanosecond without the call taking 10 nanoseconds or more... – juhist Jul 1 '17 at 13:31
5

I think what happens is that sub-millisecond accuracy is around the corner and they are thinking forward.

Since a new method is needed, instead of going for microseconds the designers decided to go straight to nanoseconds. Not because there is a need today for this level of accuracy, but to be ready for the future.

The implementation that rounds the time to milliseconds is there for compatibility. You will be able to take advantage of the new method on faster computers and JVMs, while the same code will sill run on older JVMs that map the call to millisecond accuracy.

| improve this answer | |
  • 2
    You can use the new method now. When the computers get faster and the JVM is able to deal with sub-millisecond times, your program will follow. ...and then your program's timing will change, and a zillion things will break in subtle ways. – Mason Wheeler Aug 13 '14 at 22:23
  • @MasonWheeler I agree, trying to future-proof an interface and introducing bugs in the process is a bad idea. YAGNI, maybe? – user22815 Aug 14 '14 at 0:57
  • 1
    @Mason Agree. It should be seen as a placeholder for a method to be implemented someday. Whenever you need to use the new method on a fast CPU and JVM, you can use it and still be able to run your program on slower implementations of the JVM. – Florian F Aug 14 '14 at 20:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.