Check for timeout in wait() loop I want to check for a condition in a guarded wait() loop with a user-specified total timeout, similar to how LinkedBlockingQueue.poll() works.

For example collection can be appended to by different threads, but only when the collection contains a value equating to myItem within timeout, should the loop terminate successfully. If the user-specified timeout elapses, it should throw.

This is my current best approach:

long startTime = System.currentTimeMillis();
synchronized (collection) {
    while (!collection.contains(myItem)) {
        long remaining = System.currentTimeMillis() - startTime - timeout;
        if (remaining &lt; 0)
            throw new TimeoutException();

        collection.wait(remaining);
    }
}


The problem here is that System.currentTimeMillis() (or System.nanoTime()) is called inside a synchronized context. IntelliJ's warning states:


  While not necessarily representing a problem, such calls cause an expensive context switch, and are best kept out of synchronized contexts, if possible. 


I wonder how much impact this 'expensive context switch' will have in practice, with Oracle JVM 8?



This is one alternative I came up with, but I don't like this as the actual timeout becomes ⌊timeout/10⌋*10 + delta. and the error will probably be much worse than the context switch.

synchronized (collection) {
    int loops = 0;
    while (!collection.contains(myItem)) {
        if(loops++ &gt; timeout / 10)
            throw new TimeoutException();

        collection.wait(10);
    }
}
System.currentTimeMillis() is the system clock, and can change if someone changes the current date / time.  It's not really a good way to accurately measure elapsed time.  Use System.nanoTime() instead, which is invariant to system clock changes.