Search code examples
javamultithreadingjava-threads

Creating threads recursively in java


I have this code that creates threads recursively and I can't seem to figure out how it stops the threads from running.

public class Recursive_Thread {

public static void main(String[] args) {

    int numThreads = 10;

    /* create and start thread 0 */

    System.out.println("Starting thread 0");
    Thread thread = new Thread(new Inner(0, numThreads));
    thread.start();        

    /* wait for thread 0 */

    try {
        thread.join();
    } catch (InterruptedException e) {}

    System.out.println("Threads all done");
}
/* inner class containing code for each thread to execute */

private static class Inner extends Thread {

    private int myID;
    private int limit;

    public Inner(int myID, int limit) {
        this.myID = myID;
        this.limit = limit;
    }

    public void run() {
        System.out.println("Hello World from " + myID);

        /* do recursion until limit is reached */
        if (myID == limit) {
              System.out.println("Good Bye World from " + myID);
        } else {
              System.out.println("Starting thread " + (myID+1));
              Thread thread = new Thread(new Inner((myID+1), limit));
              thread.start();
              try {
                  thread.join();
              } catch (InterruptedException e) {System.out.println("Well... That didn't go as planned!");}
              System.out.println("Thread " + (myID+1) + " finished");
              System.out.println("Good Bye World from " + myID);
        }
    }

}

I ran the debugger and the execution seems to stop after going through this line after the message for the 10th thread has been printed

System.out.println("Good Bye World from " + myID);

and somehow the execution goes back to these lines

System.out.println("Thread " + (myID+1) + " finished");
System.out.println("Good Bye World from " + myID);

for every remaining thread after the 10th one. How do I get from

if (myID == limit) {
              System.out.println("Good Bye World from " + myID);

to

else {
              System.out.println("Starting thread " + (myID+1));
              Thread thread = new Thread(new Inner((myID+1), limit));
              thread.start();
              try {
                  thread.join();
              } catch (InterruptedException e) {System.out.println("Well... That didn't go as planned!");}
              System.out.println("Thread " + (myID+1) + " finished");
              System.out.println("Good Bye World from " + myID);
        }

Does the join method create some kind of checkpoint for the program to go back to after finishing with the creation of all 10 threads?


Solution

  • When you start a new thread with myId 9 the code path you will follow in the run method is the else branch. In this branch you use myId + 1 to spawn the final thread and wait for this final thread to join. On line 46 you will print the "Thread x finished" message in which you will also use myId + 1.

    So basically, the run method of thread 9 will print that thread 10 finished and the run method of thread 10 does what you correctly assumed - take the if branch and only print "Goodbye".

    Just to clarify:

    • "Hello World" is printed after the thread has started at the beginning of its run method.
    • "Good Bye" is printed when the run method approaches its end. The thread is still alive here, but will return after the printing is done.
    • "Thread X finished" is printed outside of thread X since it ended already. Outside means in the outer thread (myId - 1) or in the main thread for thread 0.
    • There is no "Thread 0 finished" message because in 0's outer thread (the main thread main) there is no such statement, but instead "Threads all done"