I have six threads running in my application. If one thread throws a StackOverFlow exception, will all threads or application stop working?
I have six threads running in my application. If one thread throws a StackOverFlow exception, will all threads or application stop working?
exception in one thread does not kill another thread;
unless....
There are two types of threads in Java: Normal Threads and Daemon Threads, and they differ only in what happens when they exit.
When a thread exits, the JVM performs an inventory of running threads, and
if only daemon threads are left alive
JVM initiates an orderly shutdown (meaning, it shuts down after main thread finishes execution).
When the JVM halts, any remaining daemon threads are abandoned — finally blocks are not executed, stacks are not unwound — the JVM just exits.
So, when you have an unhandled exception in your thread, one of two possible scenarios may occur:
For example, in this case:
public class EntryPoint {
public static void main(String[] args) throws Exception {
Thread t = new Thread(() -> {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(1000);
System.out.println("Thread " + Thread.currentThread().getName() + " " + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.setDaemon(true);
t.start();
for (int i = 0; i < 5; i++) {
Thread.sleep(1000);
if (i == 4) {
throw new StackOverflowError("JVM exits in this case.");
}
System.out.println("Call number " + i);
}
}
}
your application will crash as soon as an exception is thrown, as there are no normal threads left running;
whereas, in this case:
public class EntryPoint {
public static void main(String[] args) throws Exception {
Thread t = new Thread(() -> {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(1000);
System.out.println("Thread " + Thread.currentThread().getName() + " " + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.setDaemon(false);
t.start();
for (int i = 0; i < 5; i++) {
Thread.sleep(1000);
if (i == 4) {
throw new StackOverflowError("JVM won't exit in this case.");
}
System.out.println("Call number " + i);
}
}
}
a normal thread, referred by t, will continue its execution.
Note, that when the JVM starts up (Java program starts), all the threads it creates (such as garbage collector and other housekeeping threads) are daemon threads, except the main thread, which is a normal thread; however, if you create a new thread, it inherits the type from the thread it was created in;
The only reason I explicitly set the .setDaemon(true), in the first code snippet, is that the thread type is inherited from the thread that created it.
No.
If StackOverflowError occurs, the thread that ran the code that is responsible for it goes through the normal procedure: It will throw that throwable from that method (throwing a throwable is just like return; in the sense that it exits the method just like return would, with a result: That throwable. But it's not returned, it's thrown - to see it, you'd use a catch block). The method that invoked the method that threw the SOError now throws it. This means every method, in sequence, keeps returning, until one of two things happens:
Somewhere in this chain, the method that invoked the method that invoked the method that threw the SO was doing so in a try{} block where an associated catch block is catching StackoverflowError or some parent type of that (Error or Throwable). In that case, code continues in that catch block and the thread just keeps running at that point.
The exception bubbles all the way to the top, to the run() method where the thread started, and exits the run method in that way (by throwing it onwards). In this case, the JVM itself catches it. Threads will catch any and all throwables that the run() method they started the thread with end up throwing. In which case, the thread is of course shut down (the run() method returned - that's what threads do when the run method returns), and the throwable is handed to the thread's uncaught exception handler. You can set that handler if you want. By default, it dumps a bunch of useful info to System.err and that's all the deafult handler does.
Other threads are not affected in the slighest.
StackOverflowError smacks of OutOfMemoryError, but to be clear, they are not the same. A major caveat is often stated for OOMError, but does not apply to stack overflow: If an OOME occurs anywhere in the VM you should assume that code will end up buggy - most java code is not tested to properly handle this situation, and in practice the VM probably isn't quite guaranteeing stable behaviour in the face of a full heap either. So if an OOME happens to you, the VM is best considered unstable (exit it and restart at some point, sooner better than later), and weird things may happen.
But that's OOME. It does not apply to stack overflow, because each thread has its own, entirely independent stack.
Well, if you don't catch that SOErr the thread will end up exiting because the run() method returns, and the VM will shut down automatically if all there are no running threads* left. This isn't a particularly good strategy to shut down VMs (just call System.exit if you want the VM to shut down); it's more of a ¯\(ツ)/¯ I guess there's nothing left to do, might as well just shut down then situation.
Thus, if you have only one thread, it runs code that ends up throwing SOError, you don't catch it (and usually you shouldn't), then yeah, the VM will shut down, but by design: That thread will now exit, the VM realizes no active threads are left, and will then shut down.
*) Technically, threads with the daemon flag set do not 'count'; if all non-done threads are daemon threads, the VM shuts down. Given that VM shutdows are best done with System.exit, this factoid is essentially irrelevant.
No if it's not a main thread. Every thread in JVM has its own Stack in the memory. You can control its size by -Xss parameter.
By the way, you can easily find an answer by writing a simple application with 2 running threads. One can fail with StackOverflowError when doing infinite recursion, then you will see how the 2nd thread behaves. Give it a try.