8098798: Thread.join(ms) on Linux still affected by changes to the time-of-day clock
8210004: Thread.sleep(millis, nanos) timeout returns early
Reviewed-by: martin, igerasim
--- a/src/java.base/share/classes/java/lang/Thread.java Fri Sep 14 12:10:28 2018 -0400
+++ b/src/java.base/share/classes/java/lang/Thread.java Fri Sep 14 12:53:07 2018 -0400
@@ -35,6 +35,7 @@
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
import jdk.internal.misc.TerminatingThreadLocal;
@@ -332,7 +333,7 @@
"nanosecond timeout value out of range");
}
- if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
+ if (nanos > 0 && millis < Long.MAX_VALUE) {
millis++;
}
@@ -1291,28 +1292,23 @@
* <i>interrupted status</i> of the current thread is
* cleared when this exception is thrown.
*/
- public final synchronized void join(long millis)
+ public final synchronized void join(final long millis)
throws InterruptedException {
- long base = System.currentTimeMillis();
- long now = 0;
-
- if (millis < 0) {
- throw new IllegalArgumentException("timeout value is negative");
- }
-
- if (millis == 0) {
+ if (millis > 0) {
+ if (isAlive()) {
+ final long startTime = System.nanoTime();
+ long delay = millis;
+ do {
+ wait(delay);
+ } while (isAlive() && (delay = millis -
+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)) > 0);
+ }
+ } else if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
- while (isAlive()) {
- long delay = millis - now;
- if (delay <= 0) {
- break;
- }
- wait(delay);
- now = System.currentTimeMillis() - base;
- }
+ throw new IllegalArgumentException("timeout value is negative");
}
}
@@ -1353,7 +1349,7 @@
"nanosecond timeout value out of range");
}
- if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
+ if (nanos > 0 && millis < Long.MAX_VALUE) {
millis++;
}