2

I am reading about class Object and I found a method wait(long timeout, int nanos).

I read a description Docs Oracle Class Object and I found that:

The amount of real time, measured in nanoseconds, is given by:

1000000*timeout+nanos

Parameters:
timeout - the maximum time to wait in milliseconds.
nanos - additional time, in nanoseconds range 0-999999.

I took a look at implementation of this method (openjdk-7u40-fcs-src-b43-26_aug_2013) and I found this piece of code:

public final void wait(long timeout, int nanos) throws InterruptedException {
    if (timeout < 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 && timeout == 0)) {
        timeout++;
    }

    wait(timeout);
}

First and second ifs are obvious. Third one does nothing or just increments timeout and does not care about nanos.

My question is, how I can invoke method wait(long timeout, int nanos) which really works with given nanos?

Thank you in advance

Community
  • 1
  • 1
ruhungry
  • 4,506
  • 20
  • 54
  • 98
  • 1
    Use a different virtual machine. If you check other vm sources, you'll eventually find one which has that wait implemented in native code. You will need a os with nano timer suport as well. – Lorenzo Boccaccia Jun 05 '14 at 14:15

2 Answers2

2

Take a look at this:

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/locks/LockSupport.html#parkNanos%28long%29

Also many answers to this question may help:

Accurate Sleep for Java on Windows

Community
  • 1
  • 1
Andres
  • 10,561
  • 4
  • 45
  • 63
2

It does take into account nanos: the third if says that:

if (nanos >= 500000...
    timeout++;

which means that if we have more than 500000 nanos we'll round it up to another millisecond, otherwise, we'll round it down.

That's also compliant with the definition: 1000000*timeout+nanos after converting it back to milliseconds.

Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
  • Let's say, I would like to wait for `3000 milis` and `500005 nanos` = `3000 500005 nanos`. I run method with params `wait(3000, 500005)`. `500005 > 500000`, so it goes inside `if` and does `timeout++` and method `wait(3001)` will be invoked. In my opinion it is not the same, I did not want `wait(3000)` or `wait(3001)` what I wanted was `wait(3000, 500005)` – ruhungry Jun 05 '14 at 14:33
  • @ruhungry I understand that it's not what you wanted, but that's the way the developers of JDK implemented it. Further, due to os events like scheduler-events and context-switch - you are not guaranteed to get an exact wait time even in millis let along nanos – Nir Alfasi Jun 05 '14 at 14:37