在子线程完成执行之前主线程将退出吗?

时间:2012-03-11 02:15:26

标签: java

主线程会在子线程完成执行之前退出吗?

我读了2篇文章

http://www.cs.mtu.edu/~shene/NSF-3/e-Book/FUNDAMENTALS/thread-management.html

在上面的文章中,在“Thread Termination”中,它在Red中声明“如果父线程终止,它的所有子线程也会终止。”

http://www.roseindia.net/java/thread/overview-of-thread.shtml

在上面的文章中,该页面的最后一行指出“main()方法执行可以完成,但程序将继续运行,直到所有线程完成其执行。”

我付费他们是矛盾的。如果我错了,请专家指正。

在我的程序中,使用Main方法的程序调用2个线程的构造函数。在各个线程的构造函数中,我有start()方法。

     TestA  A = new TestA("TestA");
     TestB  B = new TestB("TestB");

     public TestA(String name) {
    System.out.println(name);
    t = new Thread(this);
    t.start();
}

我想知道会发生什么,主线程在子线程完成执行之前终止?如果是这样,孩子还是会线程,继续执行吗?

我尝试运行程序,有时候即使主线程退出,所有子线程也都会执行完毕。 在2个线程中,我正在处理一些文件。在testA线程A中,单独的1个文件有时没有得到处理。但很多时候,所有的文件都得到处理,我没有任何问题。

3 个答案:

答案 0 :(得分:26)

Java区分用户线程和另一种称为守护程序线程的线程。这两种类型的线程之间的区别在于,如果JVM确定应用程序中运行的唯一线程是守护程序线程(即,没有用户线程),则Java运行时会关闭应用程序。另一方面,如果至少有一个用户线程处于活动状态,则Java运行时将不会终止您的应用程序。

当main()方法最初从Java运行时接收控制时,它将在用户线程的上下文中执行。只要主方法线程或任何其他用户线程保持活动状态,您的应用程序就会继续执行。

在您的情况下,线程是用户线程,因此允许在主线程退出之前完成。

  

我正在处理一些文件。在testA线程A中,仅1个文件就是   有时候没有得到处理。但很多次

上述原因可能是除了线程退出之外的其他原因。它可能是文件锁,同步问题等。

https://docs.oracle.com/javase/10/docs/api/java/lang/Thread.html

  

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

     

已调用类Runtime的exit方法和安全性   经理允许退出操作。所有线程   那些不是守护程序的线程已经死亡,要么从返回   调用run方法或抛出传播的异常   超越run方法。

答案 1 :(得分:4)

后台线程将继续运行,即使MAIN线程完成。

如果你想让MAIN停止它们(例如,当MAIN完成时),让你的MAIN设置一个“保持运行”标志变量(你必须设置为“volatile”),线程偶尔会看到它。当MAIN想要阻止MAIN时,MAIN将其设置为false(变量)或null(对象)。当它为false或null时,线程必须“返回;”。

实现起来有点复杂,有很多方法,但最简单的方法是让Runnable成为一个内部类,这样你的Runnable就可以轻松共享标志。

为了获得最佳实现,请在Java applet的启动/停止例程中查找此技术。

答案 2 :(得分:2)

一旦主线程退出,它就会让孩子们接受它。也许通过“完成”第二篇文章仅仅意味着除了等待孩子之外不再有其他操作。一旦主线程调用System.exit(0);它结束了 - 每个人都死了。

假设您有两个运行的线程:threadA和threadB。在主要方法。第一个代码是终止线程的好方法 - 只是众多方法中的一种:

 threadA.start();
 threadB.start();
 final long intercept = 300;
 long startTime = System.currentTimeMillis();
 while (threadA.isAlive() && mis.isAlive()) {
    threadA.join(intercept);
if (System.currentTimeMillis() - startTime > intercept) {
   threadB.interrupt();
   threadA.interrupt();
   threadA.join();
}
}
System.exit(0);

以下是从main中删除所有线程的突然方法:

System.exit(0);