Keep JVM alive after main() returns? [duplicate] - java

I read this statement:
The main thread must be the last thread to finish execution. When the main thread stops, the program terminates.
Is it true?
I also came to know "Even if the main thread dies, the program keeps running".
This is my current understanding:
When you start a program, the JVM creates one thread to run your program.
The JVM creates one user thread for running a program. This thread is called main thread.
The main method of the class is called from the main thread.
If a program spawns new threads from the main thread, the program waits until the last thread dies.
Which one is true?

The program terminates when all non-daemon threads die (a daemon thread is a thread marked with setDaemon(true); it's usually used for utility threads). From the documentation:
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.

I read this statement: “The main thread must be the last thread to finish execution. When the main thread stops, the program terminates.”Is it true?
No, it is not. The virtual machine terminates if the last non-daemon thread has finished. It doesn't have to be the main thread.
Simple example:
public static void main(String[] args) {
System.out.println("Main thread started");
new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Second thread started");
try {
Thread.sleep(2000); // wait two seconds
} catch(Exception e){}
System.out.println("Second thread (almost) finished");
}
}).start();
System.out.println("Main thread (almost) finished");
}

When the main thread stops, the program terminates.
The program terminates when there no longer is any non-daemon thread running (or someone called System.exit). The main thread can have finished long ago.

The JVM will exit when the main thread and all non-daemon threads finish execution.
When you create a new thread, you can call Thread.setDaemon(true) to make it a daemon thread. If you do this, then the JVM will not wait until this thread finishes before execution. This is useful for any threads you create which are made to run in the background until the program stops.
If you create a new thread and do not call Thread.setDaemon(true), then the JVM will delay exit until this thread is complete, even if the main thread is finished.

When the main thread was start it'll not wait for the another thread which was created by us until they if can't use the join() of the thread class to wait for this thread. So basically if the child thread or sub thread getting more time for processing the task and you don't use the join() then main thread may be stop. To keep with main thread you must use the join() so the main thread stop after only this related thread are stop
check this link
http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join%28%29

The first statementis not exact.
The java program terminates when all non-daemon threads has been terminated or when System.exit() or Runtime.exit() is invoked.
Thread is terminated when it exited its run() method. Main thread is special because you do not explicitly implement its run() method, you implement main() instead and the main() is called from run(). So, main thread is terminated when main() is terminated.
But main thread is not neccessarely the last one.

This is the from the JVM specification 3rd Draft, so it's the most current I'm aware of:
5.7 Virtual Machine Exit
The Java virtual machine terminates all its activity and exits when either:
• All threads that are not daemon threads terminate.
• Some thread invokes the exit method of class Runtime or class System, and
the exit operation is permitted by the security manager.
There is no distinction made about the main thread, so we shouldn't assume that is the only one that it applies to.

Related

Multithreading Parent and Child thread execution in Java

This is a beginner question regarding multithreading in Java.
As per my understanding when multiple (user)threads are created to run the program or application, then there is no concept of Parent and Child threads. They are both independent user threads.
So, if the main thread finishes execution then another thread(Thread2) will still continue its execution because it will not be killed by the JVM until the Thread2's thread of execution is completed (https://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html, https://stackoverflow.com/a/9651919/6700081)
Then why am I not seeing the logs from the .log() being printed by Thread2 when the Main thread exits in the below code:
#Test
public void parentMainThreadAndChildThreadTest_WithSpringWebFlux() throws InterruptedException {
Flux<Long> infiniteFlux = Flux.interval(Duration.ofMillis(100));
infiniteFlux.subscribe((element) -> System.out.println("Value is:::" +element));
Thread.sleep(3000); //Main thread sleeps for 3 seconds
}
I see that if I increase the main thread's life by putting it to sleep then I can see the system out statements. But why aren't they displayed when the main thread is finished even though the Thread2 is still running asynchronously?
The test method is executed by the Main thread's thread of execution so what happens to the Thread2 after main thread finishes in this case?
if the main thread finishes execution then another thread(Thread2) will still continue its execution
this is true only for normal threads. Threads for thread pools usually are configured as daemon threads, which are forced to stop when all normal threads are finished.
In your case,
(element) -> System.out.println("Value is:::" +element)
is executed on a daemon thread taken from a reactor's thread pool.

How does daemon thread survive after JVM exits?

I am reading docs about Java's setDaemon() method, and got confused when I read that JVM exits without waiting for daemon threads to finish.
However, since essentially daemon threads are Java Thread's, which presumably rely on running on JVM to achieve its functionalities, how do daemon threads even survive if JVM exits before the daemon thread finishes?
They don't survive. The JVM will exit when all the threads, except the daemon ones, have died.
When you start your application, the JVM will start a single, non-daemon thread to run your static main method.
Once the main method exits, this main thread will die, and if you spawned no other non-daemon thread, the JVM will exit.
If however you started another thread, the JVM will not exit, it will wait for all the non-daemon threads to die before exiting.
If that thread you spawned is doing something vital, this is absolutely the right thing to do, however often you have some threads that are not that vital, maybe they are listening to some external event that may or may not happen.
So, in theory, you should place some code somewhere to stop all the threads you spawned to allow the JVM to exit.
Since this is error prone, it's way easier to mark such non-vital threads as daemons. If they are marked as such, the JVM will not wait for them to die before exiting, the JVM will exit and kill those threads when the "main threads" (those not marked as daemon) have died.
To put it in code, it's something like this :
public class Spawner {
public static void main(String[] args) {
Thread t = new Thread(new Runnable() {
public void run() {
while (true) {
System.out.println("I'm still alive");
}
}
});
// Try uncommenting/commenting this line
// t.setDaemon(true);
t.start();
System.out.println("Main thread has finished");
}
}
(I haven't tested this code, wrote it here directly, so it could contain stupid mistakes).
When running this code with the line commented, the thread is not deamon, so even if your main method has finished, you'll keep on having the console flooded until you stop it with CTRL+C. That is, the JVM will not exit.
If you uncomment the line, then the thread is a daemon, and soon after the main method has finished, the thread will be killed and the JVM will exit, without the need for CTRL+C.

Why doesn't daemon thread which is joined to the main() thread die when main() thread execution ends?

In the below code:
class Worker extends Thread {
Thread t;
public Worker(Thread thread) {
t=thread;
}
public void run() {
try {
t.join();
} catch(InterruptedException e) {
System.out.println("Exception is thrown and caught");
}
System.out.println(Thread.activeCount());
System.out.print("|work|");
}
public static void main(String[] args) {
Thread t=Thread.currentThread();
Worker worker = new Worker(t);
worker.setDaemon(true);
worker.start();
System.out.println("Exit from main method");
}
}
Since worker is a daemon thread joined on main() thread, |work| should never be printed since the user thread main() completes first, and since worker is a daemon thread it too is stopped when the main() thread dies.
But, the output I get is as follows :
Exit from main method
1
|work|
Please clarify this query for me.
After many many executions of the program, I have observed the following different outputs:
without Thread.sleep(1000) :
Exit from main method
2
Exit from main method
1
|work|
Exit from main method
2
|work|
with Thread.sleep(1000) :
Exit from main method
2
|work|
Exit from main method
Notice the first output without sleep() method. |work| is not printed but the thread count is shown to be 2. Does this mean main() thread execution ended after Thread.activeCount() but before |work| is printed? In third output seems like main() ended after execution of both these statements.
Now, I was never expecting Thread.activeCount() to be 2, since the daemon thread worker is joined on user thread main(), which means when Thread.activeCount() is executed, there will only be worker thread and no main() thread.
I don't know the exact details on how the VM knows when the last non-daemon thread stops running, but I can imagine 2 solutions:
a background regularly polls to see if all non-daemon threads have exited (and I doubt that's the actual solution)
a background thread joins on all the non-deamon threads, and exits the VM once all the join return
In those two situations, a race condition is possible, and the daemon thread sometimes has time to execute a few more operations after the main thread has died, and sometimes not.
I executed your code a few times, and sometimes something is printed after the main thread has exited, and sometimes not, which corroborates my theory.
When I add a Thread.sleep(100L) call after t.join(), nothing is printed except "Exit from main method".
Also note that if you look at the list of threads running in the VM (using the debugger for example), one of them is named "DestroyJavaVM". Given the name, I'd guess this is the thread which exits the JVM, concurrently to the remaining daemon threads, once the last non-daemon thread stops running.
How do you run your code?
When I run your example from command line I am getting:
Exit from main method
1
|work|
I guess you might not get activeCount and |work| printed out as JVM can just stop daemon-threads when all non-daemon threads terminated (the only one here is main thread). When that condition is met, JVM terminates remaining daemon threads and exits.
Thread javadoc says:
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.
Terminating those threads might take some time though, so your daemon thread might have a chance to execute some more instructions. When I add Thread.sleep(1000) after printing activeCount, the activeCount is still printed, but |work| is not.
Let me first attempt to answer the outputs for
without Thread.sleep(1000)
Exit from main method 2 - You have to remember your Worker thread is a daemon so the JVM is not going to wait for it to complete its execution. It is only bothered about completing the main thread execution which is a non daemon.
Now you are getting this output because "Exit from Main Method" was shown by the main thread and in the meantime worker thread ran and displayed 2 but alas unfortunately the main thread completed and the JVM did not wait for the worker thread ( being a daemon) hence 'work' was not displayed.
Exit from main method 1 |work| - Here go with the same explanation as above
B U T the worker thread was lucky ..it got enough time to display '|work|'
before the JVM completed the main thread and hurried to its exit.
Exit from main method 2 |work| - Same as previous explanation...not sure
about why active count returns 2 sometimes and 1 sometimes.
You could use similar logic for coming to conclusions for the
With Thread.sleep(1000) logic.
Tip: Also you can check the status of thread t with statement
System.out.println("status of t : " + t.getState()); just before
t.join()....you will get TERMINATED a lot..which proves that the main thread
which is the NON DAEMON has already terminated so no question of join working...
too late...

if main method completes the execution, what happens to any long running thread?

since main() runs on a thread. and as soon as the main() finishes, main-thread should stop. So if main() has invoked a long running thread which is yet to finish even after main() has done all the task. Since main() is returned, would the other threads be terminated? i guess no. but why?
public static void main(String[] s){
new LongRunningThread().start();
}
The process will terminate when there are no more non-daemon threads, killing any daemon threads if necessary. However, if you do have any non-daemon threads, those will prevent the process from terminating.
From Thread.setDaemon:
Marks this thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads.
This method must be invoked before the thread is started.
And from section 12.8 of the JLS:
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.
if your long running thread is not a daemon thread, it will not get terminated once the main thread exits. The JVM continues to run threads until the exit method of Runtime is called (and permitted to run) or all non-daemon threads have died. If your long running thread is not a daemon thread, JVM will not exit (i.e. thread will continue to be available for running).
To answer your question why, it's because making your thread a non-daemon thread means that you don't want it to be terminated abruptly, you want it to be terminated in an orderly way by running to completion or by being canceled. If your thread was killed by the JVM once main was exited that would be equivalent to making the thread a daemon.

will main thread exit before child threads complete execution? [duplicate]

This question already has answers here:
termination of program on main thread exit?
(2 answers)
Closed 7 years ago.
will main thread exit before child threads complete execution?
i read in 2 articles
http://www.cs.mtu.edu/~shene/NSF-3/e-Book/FUNDAMENTALS/thread-management.html
in the above article, In "Thread Termination" para, it states in Red " if the parent thread terminates, all of its child threads terminate as well."
http://www.roseindia.net/java/thread/overview-of-thread.shtml
in the above article, the last line in that page states "The main() method execution can finish, but the program will keep running until the all threads have complete its execution.".
i fee they are contradictory. if i am wrong, Please experts correct me.
In my program, a program with Main method calls the constructor of 2 threads . in the constructor of the respective threads, i am having the start() method .
TestA A = new TestA("TestA");
TestB B = new TestB("TestB");
public TestA(String name) {
System.out.println(name);
t = new Thread(this);
t.start();
}
i would like to know what happens, main thread terminates before child threads complete execution? if so, will the child threads anyway, continue their execution??
i tried running the program, some times all the child threads are getting executed complete even if the main thread exits.
In the 2 threads , i am processing some files. in testA thread A alone, 1 file alone is not getting processed some times. but many times, all the files are getting processed and i do not have any issues.
Java makes a distinction between a user thread and another type of thread known as a daemon thread. The difference between these two types of threads is that if the JVM determines that the only threads running in an application are daemon threads (i.e., there are no user threads), the Java runtime closes down the application. On the other hand, if at least one user thread is alive, the Java runtime won't terminate your application.
When your main() method initially receives control from the Java runtime, it executes in the context of a user thread. As long as the main-method thread or any other user thread remains alive, your application will continue to execute.
In your case, the threads are user threads and hence are allowed to complete before the main thread exits.
i am processing some files. in testA thread A alone, 1 file alone is
not getting processed some times. but many times
The reason for the above is could be something else than thread exits. It could be file locks, synchronization issue etc.
Thread (Java SE 10 & JDK 10):
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.
The background threads will keep running, even if the MAIN thread completes.
If you want MAIN to stop them (example, when MAIN is complete), have your MAIN set a "keep running" flag variable (which you must set as "volatile"), which the threads occasionally look at. MAIN sets it to false (variable) or null (object) when MAIN wants to stop them. When it's false or null, then the thread must "return;".
This is somewhat complex to implement, there are many ways, but easiest is to make your Runnable an inner class, so that your Runnable has easy sharing of the flag.
For the best implementations, look up this technique in Java applets' start/stop routines.
Once the main thread exits, it takes the children with it. Perhaps by "finish" the second article simply means no more operation other than waiting for the children. Once the main thread calls System.exit(0); it's over -- every body dies.
Say you have two threads running: threadA and threadB. in the main method. The first code is the nice way of terminating the thread -- just one of many ways:
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);
Below is an abrupt way of killing all threads from within main:
System.exit(0);

Categories

Resources