问题
In the below example, as the main-thread is not getting notified from the child thread, it should wait forever. But the main-thread is getting executed and the output of the below example is:
c
l
total: 19900
Why is the main-thread getting executed?
public class ThreadX extends Thread {
static int total = 0;
public void run() {
synchronized (this) {
for (int i = 0; i < 200; i++) {
total = total + i;
}
System.out.println("c");
}
}
public static void main(String[] args) throws InterruptedException {
ThreadX t = new ThreadX();
t.start();
synchronized (t) {
t.wait();
System.out.println("l");
}
System.out.println("total: " + total);
}
}
回答1:
Answer to the question-body
Check out Thread#join(long):
[...] As a thread terminates the
this.notifyAll
method is invoked. [...]
Notice that Thread#join()
calls that function with 0
, which means forever.
[...] A timeout of 0 means to wait forever.
So in your case here t
just calls notifyAll
when it terminates, which notifies the main-thread that is waiting on t
.
This unintuitive behaviour is the reason why they write the following in the documentation:
It is recommended that applications not use
wait
,notify
, ornotifyAll
onThread
instances.
Answer to the question-title
Check out Object#wait (or JLS (17.2.1. Wait)):
A thread can wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied.
So threads in Java can wake up at any time. A spurious wakeup is not very likely but it can happen.
来源:https://stackoverflow.com/questions/63432582/after-executing-wait-how-long-does-a-thread-wait-if-it-does-not-get-notified