8098798: Thread.join(ms) on Linux still affected by changes to the time-of-day clock
authorrriggs
Fri, 14 Sep 2018 12:53:07 -0400
changeset 51748 13d6be5fbfa5
parent 51747 9bf5205655ee
child 51749 a0f0da2c2719
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
src/java.base/share/classes/java/lang/Thread.java
--- 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++;
         }