Reputation: 337
public final synchronized void join(long millis) throwsInterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
How does wait(0) make the main thread wait until it finishes. Thread is calling wait on itself? As far as my understanding it must have a lock on itself to call wait() method? How does it notify the main thread when it finishes?
Upvotes: 3
Views: 355
Reputation: 27125
As far as my understanding it must have lock on itself to call wait() method?
Not on itself, but on the Thread
object. And the caller does have a lock on the Thread
object. Notice that t.join()
is a synchronized
method.
How does it notifies to the main thread when it finishes?
Don't get confused by the difference between a Thread
and a thread. A Thread
instance is a heap object that a program uses to start and manage the life-cycle of a thread of execution in the code. It's methods often are called by other threads than the one it is managing.
If thread A calls t.join()
, it will lock the object t
, and then it will call t.wait()
as many times as it takes until the state of t
is Thread.State.TERMINATED
.
Remember that, inside each t.wait()
call, the lock is released, and then re-acquired before the wait() returns.
In the thread that is managed by t
, one of the very last things that it does is, it sets the state of t
to TERMINATED
, and then calls t.notify()
. That will wake up thread A.
Upvotes: 1
Reputation: 34628
The documentation explains the logic:
This implementation uses a loop of
this.wait
calls conditioned onthis.isAlive
. As a thread terminates thethis.notifyAll
method is invoked. It is recommended that applications not usewait
,notify
, ornotifyAll
onThread
instances.
So this implementation relies on the fact that the Thread
object does not just represent a thread, but is also an object like any other object in Java. As such, it inherits from Object
, has its own monitor and can be synchronized, have threads wait
ing on it, etc.
It must have a lock on itself to call
wait()
method?
Yes. And indeed, this method is declared synchronized
. So it synchronizes on the Thread instance itself. Once you are inside it, you have the Thread
instance's monitor. Then when wait
is called, you relinquish it, so other threads can do the same thing.
This might be a bit confusing. Your currently running thread is thread A. You are using join
on thread B. The object being synchronized on here is the instance of thread B, and this causes thread A to wait until notifyAll
is called on the same (B) instance.
When the thread B finishes, it calls notifyAll
on its own instance. So any threads that are blocked in a wait
on thread B's instance will be notified.
Upvotes: 4
Reputation: 311
obj.wait() causes current thread to sleep, until some another thread call obj.notify() .
t.join() - causes current thread to wait until thread 't' finishes
Upvotes: 0