Check for timeout in wait() loop
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.