Wednesday, 8 January 2014

How join() and yield() methods of Thread class work?

Background

A very general interview question on Threads in java. If you have 3 threads t1, t2 and t3 how would you structure your program such that t1 completes it execution before t2 and t2 before t3. To answer this question we need to know how join() method of Thread class works.

About join() method

The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing,
t.join();
causes the current thread to pause execution until t's thread terminates. 

Note : Like sleep(), join() responds to an interrupt by exiting with an InterruptedException.


Let us now understand the method behavior with an example. Run the following code

package in.blogspot.iquestions;

public class ThreadDemo implements Runnable {

    public void run() {
        try {
            System.out.println("Thread has started running. Waiting for 2 seconds");
            Thread.sleep(2000);
            System.out.println("Back from waiting.Terminating ThreadDemo now");
        } catch (InterruptedException e) {
            System.out.println("Thread was interrupted");
            e.printStackTrace();
        }
    }
    
    public static void main(String args[]) throws InterruptedException{
        System.out.println("Main thread started");
        Thread demoThread = new Thread(new ThreadDemo());
        System.out.println("Starting ThreadDemo thread");
        demoThread.start();
        demoThread.join(); //comment this line in 1st run
        System.out.println("Terminating main thread");
    }

}

What we are doing in above code is that we are running a thread ThreadDemo from our main thread. Now in 1st run comment out the demoThread.join(); line and execute the program.

Output on running without calling join()

Main thread started
Starting ThreadDemo thread
Terminating main thread
Thread has started running. Witing for 2 seconds
Back from waiting.Terminating ThreadDemo now

This shows that main thread exited before ThreadDemo thread. What we want in next run is for the main thread to wait until ThreadDemothread is executed. So in 2nd run use the join() call.

Output on running with join()

Main thread started
Starting ThreadDemo thread
Thread has started running. Waiting for 2 seconds
Back from waiting.Terminating ThreadDemo now
Terminating main thread

Here you will notice main thread will wait for ThreadDemo thread to complete it's execution. Only then the main thread continues with it's execution and terminates.

Summary of join() method of Thread class

Currently executing thread(whichever that is) will stop it's execution until the thread on which join is called has completed it's execution.

Understanding yield() method in java

 Before we go to yield() lets understand the difference between sleep() and wait() -
Main difference between wait and sleep is that wait() method release the acquired monitor when thread is waiting while Thread.sleep() method keeps the lock or monitor even if thread is waiting. Also, wait for method in Java should be called from synchronized method or block while there is no such requirement for sleep() method. 

Coming back to yield(), it's little different than wait() and sleep(), it just releases the CPU hold by Thread to give another thread an opportunity to run though it's not guaranteed who will get the CPU. It totally depends upon thread scheduler and it's even possible that the thread which calls the yield() method gets the CPU again.



I have copied yield() and diagram part from the link mentioned in the related links section below. However note that Object.notify() or Object.notifyAll() does not wake up sleeping thread. That part is not correct is diagram above.

t> UA-39527780-1 back to top