简体   繁体   中英

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?

    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

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();
    }
}

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();
}

}

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); } }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM