java中的thread.join()问题

时间:2011-02-11 06:48:51

标签: java multithreading

我的代码

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

}

有时“Thread1”会在所有数字打印之前打印出来。有什么理由吗? Thread1不应该等到主线程完成吗?

4 个答案:

答案 0 :(得分:4)

    thread1.join();
    thread1.start()

制作

    thread1.start()
    thread1.join();

它将通过thread1.start()从主线程启动一个线程,主线程将继续在下一行执行,它将看到thread1.join();,它将暂停主线程的执行,直到thread1完成。所以你的工作将完成

答案 1 :(得分:1)

通过调用Thread.join()当前线程等待您调用的线程join()

在你的情况下,你等待thread1在它开始之前完成。

如果您希望thread1等待数字完成打印,可以使用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();
    }
}

答案 2 :(得分:1)

尽管您应该在thread1.start()之前调用thread1.join(),但实际上您不知道线程何时会被执行。打印i时可能会发生这种情况,可能会发生之前或之后发生。取决于您的操作系统的线程调度机制。您的正确代码应如下所示:

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

}

答案 3 :(得分:1)

实际上,在调用join()之前,我们应该确保系统已根据我们的“.start()”请求(在start()返回之前不一定发生)启动线程,如join()并没有真正等到一个线程死掉,相反,它只是在线程没有运行时立即返回。这可以在线程启动之前或完成之后发生。请参阅Allen Holub的“驯服Java线程”,第87页。以下是我认为编写此代码的正确方法:


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

}