Java Thread.join()的行为与我预期的不一样。为什么?

Java Thread.join()的行为与我预期的不一样。为什么?,java,multithreading,Java,Multithreading,从以下位置运行此代码示例: 我希望“所有线程都已失效,正在退出主线程”出现在整个输出的末尾 但是,当我运行它时,输出总是在开头,如下所示: 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

从以下位置运行此代码示例:

我希望“所有线程都已失效,正在退出主线程”出现在整个输出的末尾

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

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

是时候标记这些问题的答案了,所以我将总结一下最终解开谜团的OP评论:

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

  • 是时候标记这些问题的答案了,所以我将总结一下最终解开谜团的OP评论:

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

  • ThreadDemo
    的代码在哪里?可能是因为这是一个糟糕的教程,它有一个从线程内部开始的线程。这是教程代码中的一个严重缺陷:
    ThreadDemo
    start()
    方法(它已经是
    线程
    )启动另一个
    线程
    @M.Prokhorov查看此特定教程并了解该线程的功能。
    start
    方法被覆盖。线程本身从未真正启动,也没有访问线程的权限。它还以一种完全没有意义的方式演示了同步(使用的公共对象没有以任何方式进行修改,同步只是序列化线程,因此使用线程的全部意义消失了)。别在意口袋妖怪的捕获和大写的变量。。。本教程应该被火烧死。
    ThreadDemo
    的代码在哪里?这可能是一个糟糕的教程,它的线程从线程内部开始。这是教程代码中的一个严重缺陷:
    ThreadDemo
    start()
    方法(它已经是
    thread
    )启动另一个
    线程
    @M.Prokhorov查看此特定教程并了解该线程的功能。
    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.");
            }
        }
    }