Java join()方法

时间:2012-03-21 08:22:59

标签: java multithreading

我有一个对我来说很奇怪的例子。

public class Join {
    public static void main(String[] args) {
        Thread t1 = new Thread(
                new Runnable() {
                    public void run() {
                        System.out.println(Thread.currentThread().getName());
                    }
                }
        );
        Thread t2 = new Thread(t1);
        t1.setName("t1");
        t2.setName("t2");
        t1.start();
        try {t1.join();} catch (InterruptedException ie) {}
        t2.start();
    }
}

我们只看到打印t1。 如果我们将评论“t1.join”,我们将得到预期的输出(t1 t2)。 为什么?

3 个答案:

答案 0 :(得分:10)

第二个主题创建错误:

Thread t2 = new Thread(t1);

我无法通过文档支持它,但在Thread.run()的源代码中,我看到了:

if (target != null) {
    target.run();
}

其中targetRunnable个实例。完成Thread后,它会清除target变量:

private void exit() {
  //...
  target = null;

这意味着当第一个线程完成(join()方法)时,它会清除target,而第二个线程什么都不做。移除join()后,两者都会访问target t1(竞争条件)。

TL; DR

永远不要使用其他线程实例创建线程(即使它实现了Runnable)。而是创建一个单独的Runnable并传递它:

final Runnable run = new Runnable() {
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
};
Thread t1 = new Thread(run, "t1");
Thread t2 = new Thread(run, "t2");  //new Thread(t1, "t2"); is incorrect!
t1.start();
t2.start();

这里不需要任何join(),默认情况下这些是非守护程序线程。

另见

答案 1 :(得分:0)

这是因为当您致电t1时,主线程会等待t1.join()死亡。 当你这样做时

Thread t2 = new Thread(t1);

您正在传递t1作为调用run方法的目标对象。

答案 2 :(得分:0)

t2.start();之前添加:

System.out.println("t1 is alive: " + t1.isAlive());

如果main帖子等待t1死亡,则t2.start()无法运行t1的{​​{1}}方法。否则,无需等待run死亡,t1可以运行t2的{​​{1}}方法。