Search code examples
javaconcurrencyjava-threads

Main not waiting for threads even after using Thread.join() in Java


join() is supposed to make main function wait until all the threads complete execution, but main is printing completed before Thread-1 and Thread-2 completes execution. I am unable to find error in the code. where's the mistake?

class ThreadDemo extends Thread {
    private Thread t;
    private String threadName;

    ThreadDemo(String name) {
        threadName = name;
    }
    public void run() {
        System.out.println("Thread " + threadName + " exiting.");
    }
    public void start() {
        if (t == null) {
            t = new Thread (this, threadName);
            t.start();
        }
    }
}
public class Problem2 {
    public static void main(String[] args) {
        ThreadDemo T1 = new ThreadDemo("Thread-1");
        ThreadDemo T2 = new ThreadDemo("Thread-2");
        T1.start();
        T2.start();
        try {
            T1.join();
            T2.join();
        } catch (InterruptedException e) {
            System.out.println("ERROR!");
        }
        System.out.println("completed");
    }
}

Output

completed
Thread Thread-2 exiting.
Thread Thread-1 exiting.

Solution

  • You're joining on the ThreadDemo instances. But you're not running these instances as threads. Your overridden start method creates and starts another Thread.

    Your code is extremely convoluted. You use both inheritance and delegation, and you override methods and break their contract: start() is supposed to start this as a thread, not create and start another thread.

    Here's what it should look like:

    class ThreadDemo implements Runnable {
        private String threadName;
    
        ThreadDemo(String name) {
            this.threadName = name;
        }
    
        @Override
        public void run() {
            System.out.println("Thread " + threadName + " exiting.");
        }
    
    }
    public class Problem2 {
        public static void main(String[] args) {
            ThreadDemo runnable1 = new ThreadDemo("Thread-1");
            ThreadDemo runnable2 = new ThreadDemo("Thread-2");
    
            Thread t1 = new Thread(runnable1);
            Thread t2 = new Thread(runnable2);
    
            t1.start();
            t2.start();
            try {
                t1.join();
                t2.join();
            } catch (InterruptedException e) {
                System.out.println("ERROR!");
            }
            System.out.println("completed");
        }
    }