首页 > 解决方案 > 如果我们不使用 join(),为什么多线程 C++ 程序会崩溃,而类似的 Java 程序不会

问题描述

假设我们有以下 C++ 程序

void hello (){
   std :: cout << "HELLO"<<std::endl ;
}

int main(){

    std:: thread t(hello) ;
    t.join() ;

}

如果我们不在这段代码中调用 join,我们的程序将会崩溃,因为主线程会在线程 t1 完成之前终止。但是如果我们在 Java 中有相同的程序,即使 main 不等待线程,程序也会正常执行。

public class HelloWorld {
    public static void main(String[] args) {
        Thread t = new Thread(new Hello());
        t.start();

    }

}

class Hello implements Runnable {

    public void run() {

          System.out.println("Hello") ;

}
}

那么为什么在 Java 中程序不会崩溃呢?即使主线程先完成,线程如何执行?

标签: javac++multithreadingrunnable

解决方案


这相当简单:与 C++ 相比,它main在完成后终止,Java 程序只有在所有(非守护程序)线程(包括主线程)都完成时才结束(例如,参见这个oracle 线程文档):

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

一种。已调用 Runtime 类的退出方法,并且安全管理器已允许进行退出操作。

湾。所有不是守护线程的线程都已经死亡,要么通过调用 run 方法返回,要么抛出传播到 run 方法之外的异常。

相比之下,C++ 将开始破坏具有静态存储持续时间的对象,如果分离的线程仍在运行并访问这些对象,则会产生未定义的行为(例如,参见有关程序终止C++ 标准草案):

3.6.3 终止

作为从 main 返回的结果和调用 std::退出([support.start.term])。


推荐阅读