Aravind
Aravind

Reputation: 2198

thread.join() problem in java

My Code

public class Main {

    public static void main(String[] args)throws Exception {
        Thread thread1=new Thread(new Runnable()
        {
            public void run()
            {
                System.out.println("Thread1");
            }
        });
        thread1.join();
        thread1.start();
        for (int i = 0; i < 1000; i++) {
            System.out.println(i);
        }
    }

}

Sometimes "Thread1" gets printed even before all the numbers get printed. Any reason for that? Shouldn't Thread1 should wait until main thread gets completed?

Upvotes: 1

Views: 3794

Answers (4)

Lyle
Lyle

Reputation: 57

Actually, we should make sure the system has started the thread in accordance with our ".start()" request (which doesn't necessarily happen before start() returns), before invoking join(), as join() does not really wait until a thread dies, rather, it simply returns as soon as a thread isn't running. This can happen before the thread starts, or after it finishes. See "Taming Java Threads" by Allen Holub, page 87. Here is what I feel is the correct way to write this code:


import java.util.concurrent.Semaphore;

public class Main {

public static void main(String[] args)throws Exception { final Semaphore waitForThreadToStart = new Semaphore (0); Thread thread1=new Thread(new Runnable() { public void run() { waitForThreadToStart.release(); System.out.println("Thread1"); } }); thread1.start(); waitForThreadToStart.acquire(); // Wait for thread to start thread1.join(); // Now do the join. for (int i = 0; i < 10; i++) { System.out.println(i); } }

}

Upvotes: 1

The Scrum Meister
The Scrum Meister

Reputation: 30111

By calling Thread.join() The current thread waits for the thread you are calling join().

In you case you are waiting for thread1 to complete before it even started.

If you want thread1 to wait for the numbers to complete printing, you can use a CountDownLatch docs:

public class Main {
    public static final CountDownLatch startSignal = new CountDownLatch(1);
    public static void main(String[] args)throws Exception {
        Thread thread1=new Thread(new Runnable()
        {
            public void run()
            {
                try {
                    startSignal.await();
                    System.out.println("Thread1");
                } catch (InterruptedException ex) {}
            }
        });
        thread1.start();
        for (int i = 0; i < 1000; i++) {
            System.out.println(i);
        }
        startSignal.countDown();
        thread1.join();
    }
}

Upvotes: 1

Lars Blumberg
Lars Blumberg

Reputation: 21371

Despite the fact that you should call thread1.start() before thread1.join() you actually don't know when the thread will be executed. It can happen while printing your i, it could happen before or it could happen after. Depends on the thread scheduling mechanism of your OS. Your correct code should look like this:

public class Main {

public static void main(String[] args)throws Exception {
    Thread thread1=new Thread(new Runnable()
    {
        public void run()
        {
            System.out.println("Thread1");
        }
    });
    // start the thread
    thread1.start();
    // print the numbers... meanwhile your thread *could* get executed
    for (int i = 0; i < 1000; i++) {
        System.out.println(i);
    }
    // wait for thread1 to finish
    thread1.join();
}

}

Upvotes: 1

Jigar Joshi
Jigar Joshi

Reputation: 240900

    thread1.join();
    thread1.start()

make it

    thread1.start()
    thread1.join();

It will start a thread from main thread by thread1.start() and main thread will continue to execute at the very next line it will see thread1.join(); which will pause main thread's execution until thread1 finishes. so your work will get done

Upvotes: 4

Related Questions