Thread.join()的行为不符合我的预期。为什么?

时间:2017-03-27 17:18:22

标签: java multithreading

https://www.tutorialspoint.com/java/java_thread_synchronization.htm运行此代码示例:

public class TestThread {
    public static void main(String args[]) {

        PrintDemo PD = new PrintDemo();

        ThreadDemo T1 = new ThreadDemo("Thread One", PD);
        ThreadDemo T2 = new ThreadDemo("Thread Two", PD);

        T1.start();
        T2.start();

        // wait for threads to end
        try {
        T1.join();
        T2.join();
        } catch (Exception e) {
            System.out.println("Interrupted");
        }

        System.out.println("All threads are dead, exiting main thread");
    }
}

我希望"所有线程都已死,退出主线程"出现在整个输出的结束

但是,当我运行它时,输出始终在开头,如下所示:

Starting Thread One
Starting Thread Two
All threads are dead, exiting main thread
Counter of Thread-0 --- 5
Counter of Thread-0 --- 4
Counter of Thread-0 --- 3
Counter of Thread-0 --- 2
Counter of Thread-0 --- 1
Thread One exiting.
Counter of Thread-1 --- 5
Counter of Thread-1 --- 4
Counter of Thread-1 --- 3
Counter of Thread-1 --- 2
Counter of Thread-1 --- 1
Thread Two exiting.

如果删除两个join()语句,输出完全相同。

我认为join()等待当前线程(在这种情况下是主进程)死掉。

我错过了什么?

更新:我在这里发布了本文开头提供的链接中的其余代码:

public class ThreadDemo extends Thread {
    private Thread t;
    private String threadName;
    PrintDemo PD;

    ThreadDemo(String name, PrintDemo pd) {
        threadName = name;
        PD = pd;
    }

    public void run() {
        synchronized (PD) {
            PD.printCount(this.getName());
        }
        System.out.println(threadName + " exiting.");
    }

    public void start() {
        System.out.println("Starting " + threadName);
        if (t == null) {
            t = new Thread(this, threadName);
            t.start();
        }
    }
}

和...

public class PrintDemo {
    public void printCount(String threadName) {
        try {
            for (int i = 5; i > 0; i--) {
                System.out.println("Counter of " + threadName + " --- " + i);
            }
        } catch (Exception e) {
            System.out.println("Thread  interrupted.");
        }
    }
}

1 个答案:

答案 0 :(得分:2)

是时候将这些问题标记为已回答,所以我将总结对最终解决这个谜团的OP的评论:

  1. 问题不在TestThread的main()中,而是在ThreadDemo类中。
  2. 更具体地说,ThreadDemo的start()方法不会自行启动。而是实例化一个新的Thread,然后启动它。但是,由于调用start(),JVM本身调用了ThreadDemo的run(),这解释了为什么我们根本看不到“线程一/二退出”。
  3. “所有线程已死,正在退出主线程” 会被打印在所有其他消息之前,这仅仅是因为由ThreadDemo.start()开始的未命名线程会立即退出。