Java的main方法线程为什么不会执行完就关了?

在Java中,main方法是一个程序的入口点,程序会从main方法开始执行。然而,我们经常会遇到这样的情况,即使在main方法的最后一行代码执行完毕后,程序并不会立即结束而是继续运行一段时间。那么,为什么main方法线程不会执行完就关了呢?

Java程序的多线程特性

要理解为什么main方法线程不会执行完就关了,首先需要了解Java程序的多线程特性。在Java中,可以通过创建线程来实现多任务并发执行。每个线程都是一个独立的执行路径,可以独立执行代码。

main方法的执行过程

我们来看一个简单的示例代码,来说明main方法的执行过程。

public class MainThreadExample {
  
  public static void main(String[] args) {
    System.out.println("Main thread starts");
    
    Thread thread = new Thread(new Runnable(){
      @Override
      public void run() {
        System.out.println("New thread starts");
        try {
          Thread.sleep(5000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        System.out.println("New thread ends");
      }
    });
    thread.start();
    
    System.out.println("Main thread ends");
  }
}

在这个示例代码中,我们创建了一个新的线程并启动它。新线程会休眠5秒钟,然后输出一段文字。

main方法的线程和新线程的关系

当我们运行这段代码时,main方法的线程和新线程会并发执行。由于新线程会休眠5秒钟,所以在这段时间内,main方法的线程还会继续执行。当新线程休眠结束后,它会继续执行,并输出一段文字。

main方法线程的结束时机

回到我们的问题,为什么main方法线程不会执行完就关了呢?其实,main方法线程的结束时机是与所有非守护线程的执行情况有关的。

在Java中,线程分为守护线程和非守护线程。守护线程是为其他线程提供服务的线程,只有当所有非守护线程结束后,守护线程才会退出。而main方法线程是非守护线程,所以只有当所有非守护线程结束后,main方法线程才会结束。

在我们的示例代码中,main方法线程和新线程是并发执行的。当新线程休眠结束后,它会继续执行,并输出一段文字。这段文字的输出会在main方法最后一行代码执行之前。因此,在main方法最后一行代码执行之前,新线程并没有结束。由于新线程是非守护线程,所以main方法线程会等待新线程结束后,才会结束。

流程图

下面是以上示例代码的执行流程图:

flowchart TD
  A(Main thread) --> B(Create new thread)
  B --> C(Main thread ends)
  B --> D(New thread starts)
  D --> E(New thread ends)

结论

通过以上分析,我们可以得出结论:main方法线程不会执行完就关了,是因为它要等待所有非守护线程执行完毕后才会结束。

在实际开发中,我们需要注意这一点。如果在main方法中启动了其他线程,而这些线程没有正确地结束,就有可能导致程序不能正常退出,从而产生一些问题。

为了避免这种情况的发生,我们可以通过调用Thread的join方法来等待其他线程执行完毕。join方法会阻塞当前线程,直到调用join方法的线程执行完毕。

thread.join();

在我们的示例代码中,可以在main方法的最后一行代码之前,加上以上代码来保证新线程执行完毕后,main方法线程才会结束。

综上所述,主线程在Java程序中不会在执行完毕后立即关闭,而是会等待所有非守护线程执行完毕