-
Bug
-
Resolution: Duplicate
-
P4
-
None
-
9, 10, 11
-
x86_64
-
windows
FULL PRODUCT VERSION :
java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.16299.309]
A DESCRIPTION OF THE PROBLEM :
The Thread.join(long millis) function uses System.currentTimeMillis() to measure elapsed time. This is a faulty behaviour as it depends on the system time. The function should use System.nanoTime() instead.
The attached testcase showcases that if the user changes the system date while the main thread is waiting for the first to finish, the join method can take significantly longer time to complete.
This bug rarely occurs, but it distrupt expected application flow. The bug can occur when daylight savings time is being used.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached test case, and while the main thread is waiting, set the system date 1 hour backward.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
ThreadJoinDeadlock.main() started
ThreadJoinDeadlock.main(...).new Thread() {...}.run() thread running
ThreadJoinDeadlock.main() end join after 10000 ms
ACTUAL -
ThreadJoinDeadlock.main() started
ThreadJoinDeadlock.main(...).new Thread() {...}.run() thread running
ThreadJoinDeadlock.main(...).new Thread() {...}.run() thread exit
ThreadJoinDeadlock.main() end join after 60001 ms
REPRODUCIBILITY :
This bug can be reproduced rarely.
---------- BEGIN SOURCE ----------
package test;
public class ThreadJoinDeadlock {
public static void main(String[] args) {
Thread t = new Thread() {
@Override
public void run() {
System.out.println("ThreadJoinDeadlock.main(...).new Thread() {...}.run() thread running");
try {
Thread.sleep(60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadJoinDeadlock.main(...).new Thread() {...}.run() thread exit");
}
};
t.setDaemon(true);
long joinstart = System.nanoTime();
System.out.println("ThreadJoinDeadlock.main() started");
t.start();
try {
t.join(10 * 1000);
} catch (InterruptedException e) {
}
long joinend = System.nanoTime();
System.out.println("ThreadJoinDeadlock.main() end join after " + (joinend - joinstart) / 1_000_000 + " ms");
}
}
---------- END SOURCE ----------
java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.16299.309]
A DESCRIPTION OF THE PROBLEM :
The Thread.join(long millis) function uses System.currentTimeMillis() to measure elapsed time. This is a faulty behaviour as it depends on the system time. The function should use System.nanoTime() instead.
The attached testcase showcases that if the user changes the system date while the main thread is waiting for the first to finish, the join method can take significantly longer time to complete.
This bug rarely occurs, but it distrupt expected application flow. The bug can occur when daylight savings time is being used.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached test case, and while the main thread is waiting, set the system date 1 hour backward.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
ThreadJoinDeadlock.main() started
ThreadJoinDeadlock.main(...).new Thread() {...}.run() thread running
ThreadJoinDeadlock.main() end join after 10000 ms
ACTUAL -
ThreadJoinDeadlock.main() started
ThreadJoinDeadlock.main(...).new Thread() {...}.run() thread running
ThreadJoinDeadlock.main(...).new Thread() {...}.run() thread exit
ThreadJoinDeadlock.main() end join after 60001 ms
REPRODUCIBILITY :
This bug can be reproduced rarely.
---------- BEGIN SOURCE ----------
package test;
public class ThreadJoinDeadlock {
public static void main(String[] args) {
Thread t = new Thread() {
@Override
public void run() {
System.out.println("ThreadJoinDeadlock.main(...).new Thread() {...}.run() thread running");
try {
Thread.sleep(60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadJoinDeadlock.main(...).new Thread() {...}.run() thread exit");
}
};
t.setDaemon(true);
long joinstart = System.nanoTime();
System.out.println("ThreadJoinDeadlock.main() started");
t.start();
try {
t.join(10 * 1000);
} catch (InterruptedException e) {
}
long joinend = System.nanoTime();
System.out.println("ThreadJoinDeadlock.main() end join after " + (joinend - joinstart) / 1_000_000 + " ms");
}
}
---------- END SOURCE ----------
- duplicates
-
JDK-8098798 Thread.join(ms) on Linux still affected by changes to the time-of-day clock
-
- Closed
-