Manu
Manu

Reputation: 337

Can someone explain join method in Java Thread class?

    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

Answers (3)

Solomon Slow
Solomon Slow

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

RealSkeptic
RealSkeptic

Reputation: 34628

The documentation explains the logic:

This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread 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 waiting 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

Eldar Budagov
Eldar Budagov

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

Related Questions