【问题标题】:When does the main thread stop in Java?Java中的主线程什么时候停止?
【发布时间】:2011-11-16 23:28:20
【问题描述】:

我读了这个声明:

主线程必须是完成执行的最后一个线程。当主线程停止时,程序终止。

是真的吗?

我也知道了“即使主线程死了,程序也会继续运行”。

这是我目前的理解:

  • 当您启动一个程序时,JVM 会创建一个线程来运行您的程序。
  • JVM 创建一个用户线程来运行程序。该线程称为主线程。
  • 类的main方法是从主线程调用的。
  • 如果程序从主线程产生新线程,程序会一直等待,直到最后一个线程终止。

哪一个是真的?

【问题讨论】:

  • 你能提供这些报价的链接吗?
  • @Steve:它们似乎来自一些相对晦涩的 Java 常见问题解答。您在 Google 上的第一条报价获得大约 50 次准确点击。
  • 根据this post,它来自 Java2:完整参考(第 11 章,第 277 页,倒数第二行)。

标签: java multithreading jvm


【解决方案1】:

当所有非守护线程都死掉时程序终止(守护线程是标记为setDaemon(true)的线程;它通常用于实用线程)。来自documentation:

当 Java 虚拟机启动时,通常有一个非守护线程(通常调用某个指定类的名为 main 的方法)。 Java 虚拟机继续执行线程,直到发生以下任一情况:

  • 已调用 Runtime 类的退出方法,并且安全管理器已允许执行退出操作。
  • 不是守护线程的所有线程都已死亡,要么从调用 run 方法返回,要么抛出传播到 run 方法之外的异常。

【讨论】:

    【解决方案2】:

    我读到这句话:“主线程必须是完成执行的最后一个线程。当主线程停止时,程序终止。”是真的吗?

    不,不是。如果最后一个非守护线程完成,虚拟机将终止。它不一定是主线程。

    简单示例:

    public static void main(String[] args) {
    
       System.out.println("Main thread started");
       new Thread(new Runnable() {
         @Override
         public void run() {
            System.out.println("Second thread started");
            try {
              Thread.sleep(2000);  // wait two seconds
            } catch(Exception e){}
            System.out.println("Second thread (almost) finished");
         }
       }).start();
       System.out.println("Main thread (almost) finished");
    }
    

    【讨论】:

    • 两个打印行应该说“线程完成”而不是“线程(几乎)完成”吗?主线程在到达main 的末尾时结束,第二个线程将在到达run 的末尾时结束。
    【解决方案3】:

    当主线程停止时,程序终止。

    当不再有任何非守护线程运行(或称为 System.exit 的人)时,程序终止。主线程可能早就结束了。

    【讨论】:

      【解决方案4】:

      当主线程和所有非守护线程执行完毕后,JVM会退出。

      创建新线程时,可以调用Thread.setDaemon(true) 使其成为守护线程。如果这样做,那么 JVM 将不会等到该线程完成后再执行。这对于您创建的任何在后台运行直到程序停止的线程很有用。

      如果你创建了一个新线程并且不调用Thread.setDaemon(true),那么JVM会延迟退出直到这个线程完成,即使主线程已经完成。

      【讨论】:

        【解决方案5】:

        当主线程启动时,它不会等待我们创建的另一个线程,直到他们不能使用线程类的 join() 来等待这个线程。所以基本上如果子线程或子线程有更多时间来处理任务并且你不使用 join() 那么主线程可能会停止。为了与主线程保持一致,您必须使用 join() 以便仅在此相关线程停止后主线程停止

        查看此链接

        http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join%28%29

        【讨论】:

          【解决方案6】:

          第一个说法不准确。 当所有非守护线程都已终止或调用System.exit() 或Runtime.exit() 时,java 程序将终止。

          线程在退出其run() 方法时终止。主线程很特别,因为您没有显式实现其run() 方法,而是实现main(),并且main() 是从run() 调用的。所以,当main() 终止时,主线程也终止了。

          但主线程不一定是最后一个。

          【讨论】:

            【解决方案7】:

            这是来自 JVM 规范 3rd Draft,所以它是我所知道的最新版本:

            5.7 虚拟机退出

            Java 虚拟机终止其所有活动并在以下情况下退出: • 所有不是守护线程的线程都会终止。 • 某个线程调用了Runtime 类或System 类的exit 方法,并且 安全管理员允许退出操作。

            主线程没有区别,所以我们不应该假设它是唯一适用的。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-09-22
              • 2014-06-10
              • 2020-03-18
              • 2018-02-17
              • 2021-11-22
              • 1970-01-01
              相关资源
              最近更新 更多