Reputation: 39354
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.
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.
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?
Upvotes: 36
Views: 15187
Reputation: 71
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).
Upvotes: 0
Reputation: 14728
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.
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.
If you want JVM to terminate even if a thread t
is running, you should make thread t
a daemon thread:
t.setDaemon(true);
Upvotes: 13
Reputation: 500913
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.
Upvotes: 12
Reputation: 11120
The Java Language Specification section 12.8 indicates:
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.
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#setDaemon or use Thread#join as you initially suggested.
Upvotes: 7
Reputation: 692231
Because that's how it works. The program exits when System.exit()
is called, or when the last non-daemon thread stops running.
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.
Upvotes: 32
Reputation: 3510
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:
Thread t = new Thread(...);
t.setDaemon(true);
All non-daemon threads are user threads. Those threads are stopping the jvm from closing.
Upvotes: 29