Joining – Concurrency: Part I

Joining

A thread can invoke the overloaded method join() (from the Thread class) on another thread in order to wait for the other thread to complete its execution before continuing—that is, the first thread waits for the second thread to join it after completion.

A running thread t1 invokes the method join() on a thread t2. The join() call has no effect if thread t2 has already completed. If thread t2 is still alive, thread t1 transits to one of the two waiting states. Depending on whether a timeout was specified or not in the call to the join() method, a call to the getState() method on thread t1 while it is waiting for join completion will return the value Thread.State.TIMED-_WAITING or Thread.State.WAITING, respectively.

Thread t1 waits in a waiting state until one of these events occurs (Figure 22.11):

  • Thread t2 completes.

In this case, thread t1 moves to the READY substate, and when it gets to run, it will continue normally after the call to the join() method.

  • Thread t1 is timed out.

The time specified in the argument of the join() method call has elapsed without thread t2 completing. In this case as well, thread t1 transits from the TIMED_WAITING state to the READY substate. When it gets to run, it will continue normally after the call to the join() method.

If the no-argument join() method was called, there is no timeout for thread t1 in the WAITING state. It waits indefinitely in this state for one of the other events to occur.

  • Thread t1 is interrupted.

Some thread interrupted thread t1 while it was waiting for join completion. Thread t1 transits to the READY substate, but when it gets to execute, it will now receive an InterruptedException.

Figure 22.11 Timed Joining of Threads

Example 22.7 illustrates joining of threads. The AnotherClient class below uses the Counter class, which extends the Thread class, from Example 22.2. It creates two threads that are enabled for execution. The main thread invokes the join() method on the Counter A thread. If the Counter A thread has not already completed, the main thread transits to the WAITING state, as no timeout is specified. When the Counter A thread completes, the main thread will be enabled for running. Once the main thread is running, it continues with execution after (5). A parent thread can call the isAlive() method to find out whether its child threads are alive, before terminating itself. The call to the isAlive() method on the Counter A thread at (6) correctly reports that the Counter A thread is not alive. A similar scenario transpires between the main thread and the Counter B thread. At most, the main thread passes through the WAITING state twice.

Example 22.7 Joining of Threads

Click here to view code image

class Counter extends Thread { /* See
Example 22.2
,
p. 1376
. */ }

Click here to view code image

public class AnotherClient {
  public static void main(String[] args) {
    // Create two Counter threads, set their names, and start them:    // (4)
    Counter counterA = new Counter();
    Counter counterB = new Counter();
    counterA.setName(“counterA”);
    counterB.setName(“counterB”);
    counterA.start();
    counterB.start();
    try {
      System.out.println(“Wait for the child threads to finish.”);
      counterA.join();                                                 // (5)
      if (!counterA.isAlive()) {                                       // (6)
        System.out.println(“Counter A not alive.”);
      }
      counterB.join();                                                 // (7)
      if (!counterB.isAlive()) {
        System.out.println(“Counter B not alive.”);
      }
    } catch (InterruptedException ie) {
      System.out.println(“main thread interrupted.”);
    }
    System.out.println(“Exiting from main thread.”);
  }
}

Probable output from the program:

Click here to view code image

Wait for the child threads to finish.
counterB: 0
counterA: 0
counterA: 1
counterB: 1
counterA: 2
counterB: 2
counterA: 3
counterB: 3
counterA: 4
counterB: 4
Exiting counterB
Exiting counterA
Counter A not alive.
Counter B not alive.
Exiting from main thread.

Leave a Reply

Your email address will not be published. Required fields are marked *