为什么线程比 Java 中的 main 方法寿命长?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13904745/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does a thread outlive the main method in Java?
提问by John Humphreys - w00te
I was teaching myself Java threading and I noticed something that confuses me a little. I made a class called engine
implementing Runnable
. The run method just prints "Hello World", sleeps for a second, and repeats.
我正在自学 Java 线程,但我注意到一些让我感到困惑的事情。我做了一个叫做engine
实现的类Runnable
。run 方法只是打印“Hello World”,休眠一秒钟,然后重复。
In my main method, I have:
在我的主要方法中,我有:
public static void main(String[] args) {
Thread thread = new Thread(engine);
thread.start();
System.out.println("Done.");
}
As I expected, I see "Hello World" and "Done." printed quickly, meaning the main method has reached the end, but what I didn't expect was that the thread I started kept running even after the end of main was reached.
正如我所料,我看到了“Hello World”和“Done”。打印很快,意味着main方法已经到了最后,但没想到的是,我开始的线程即使在main结束后也一直在运行。
Why does the program continue to execute even after main exits? I would have thought that when main exited the process would terminate and all of the threads would be cleaned up forcefully. Does this mean that every thread has to be joined/killed explicitly for a Java program to terminate?
为什么程序在 main 退出后继续执行?我原以为当 main 退出时,进程会终止,所有线程都会被强制清理。这是否意味着每个线程都必须显式地加入/终止,Java 程序才能终止?
采纳答案by Zhedar
If you want your program to exit when the main method finished, consider making your threads daemons. But take care of the fact, that daemon threads will be aborted, when main finishes.
You can create a daemon thead like so:
如果您希望您的程序在 main 方法完成时退出,请考虑使您的线程成为守护进程。但请注意,当 main 完成时,守护线程将被中止。
你可以像这样创建一个守护进程:
Thread t = new Thread(...);
t.setDaemon(true);
All non-daemon threads are user threads. Those threads are stopping the jvm from closing.
所有非守护线程都是用户线程。这些线程正在阻止 jvm 关闭。
回答by JB Nizet
Because that's how it works. The program exits when System.exit()
is called, or when the last non-daemon thread stops running.
因为这就是它的工作原理。程序在System.exit()
被调用时退出,或者在最后一个非守护线程停止运行时退出。
And it makes sense. Without this rule, every Java program consisting in just spawning a GUI, for example, would have to wait() infinitely to avoid the program from exiting immediately.
这是有道理的。如果没有这条规则,例如,每个只包含生成 GUI 的 Java 程序都必须无限期地 wait() 以避免程序立即退出。
回答by reprogrammer
User threads continue to run independently of the lifetime of their parent thread, i.e, the creator thread. So, you have to join the threads explicitly by invoking Thread.join
before the main
thread terminates.
用户线程独立于其父线程(即创建者线程)的生命周期继续运行。因此,您必须Thread.join
在main
线程终止之前通过调用显式加入线程。
From the Javadoc of Thread
:
When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class). The Java Virtual Machine continues to execute threads until either of the following occurs:
The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.
当 Java 虚拟机启动时,通常会有一个非守护线程(通常调用某个指定类的名为 main 的方法)。Java 虚拟机继续执行线程,直到发生以下任一情况:
已调用 Runtime 类的退出方法并且安全管理器已允许退出操作发生。
所有不是守护线程的线程都已经死了,要么是从对 run 方法的调用返回,要么是通过抛出传播到 run 方法之外的异常。
If you want JVM to terminate even if a thread t
is running, you should make thread t
a daemon thread:
如果您希望 JVM 即使线程t
正在运行也终止,您应该使线程t
成为守护线程:
t.setDaemon(true);
回答by NPE
There are two types of threads, user and daemon. The process terminates when there are no more user threads. The main thread is always a user thread. The thread that you start is also a user thread, and therefore keeps the process alive for as long as it runs.
有两种类型的线程,用户和守护进程。当没有更多用户线程时,进程终止。主线程始终是用户线程。您启动的线程也是用户线程,因此只要进程运行,它就会保持活动状态。
Calling setDaemon(true)
on your thread before you start it will make your process terminate (more or less) as soon are your main()
function returns.
setDaemon(true)
在您开始之前调用您的线程将使您的进程在您的main()
函数返回时立即终止(或多或少)。
回答by Aviram Segal
The Java Language Specification section 12.8indicates:
在Java语言规范部分12.8表明:
12.8. Program Exit
A program terminates all its activity and exits when one of two things happens:
All the threads that are not daemon threads terminate.
Some thread invokes the exit method of class Runtime or class System, and the exit operation is not forbidden by the security manager.
12.8. 程序退出
当发生以下两种情况之一时,程序将终止其所有活动并退出:
所有不是守护线程的线程都将终止。
某些线程调用了 Runtime 类或 System 类的退出方法,退出操作不受安全管理器的禁止。
This means it is not enough for the main thread to finish.
这意味着主线程完成是不够的。
If you do want it to exit when the main thread ends you need to either make the new thread a daemon by using Thread#setDaemonor use Thread#joinas you initially suggested.
如果您确实希望它在主线程结束时退出,您需要使用Thread#setDaemon或使用最初建议的Thread#join使新线程成为守护程序。
回答by leo
The main thread is also a user thread which is being created and its lifecylce is similar to any other user thread for that matter.
The other user threads are not dependent on the main thread for any reason unless you set the threads as daemon threads.
Once the main thread completes its work it ends(it neither ends the other user threads nor will end the process because the other user threads are running).
主线程也是一个正在创建的用户线程,它的生命周期类似于任何其他用户线程。
除非您将线程设置为守护线程,否则其他用户线程不会出于任何原因依赖于主线程。一旦主线程完成其工作,它就会结束(它既不会结束其他用户线程,也不会结束进程,因为其他用户线程正在运行)。