Java join()方法

Bax*_*Bax 4 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Tom*_*icz 10

第二个线程创建错误:

Thread t2 = new Thread(t1);
Run Code Online (Sandbox Code Playgroud)

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

if (target != null) {
    target.run();
}
Run Code Online (Sandbox Code Playgroud)

哪里targetRunnable实例.当Thread完成时,它会清除target变量:

private void exit() {
  //...
  target = null;
Run Code Online (Sandbox Code Playgroud)

这意味着当第一个线程完成时(join()方法)它会清除target,第二个线程什么都不做.当join()被删除,都访问相同targett1(竞争状态).

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();
Run Code Online (Sandbox Code Playgroud)

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

也可以看看