Java can capture all the uncaught exceptions thrown by any Thread of the ThreadGroup class.
JVM looks for the uncaught exception handler for the ThreadGroup class of the thread.
If this method doesn't exist, the JVM looks for the default uncaught exception handler.
If none of the handlers exit, the JVM writes the stack trace of the exception in the console and exits the program.
import java.util.Random; public class Main { public static void main(String[] args) { // Create a MyThreadGroup object MyThreadGroup threadGroup = new MyThreadGroup("MyThreadGroup"); // Create a Task object Task task = new Task(); // Create and start two Thread objects for this Task for (int i = 0; i < 2; i++) { Thread t = new Thread(threadGroup, task); t.start();//from w w w . ja va2 s . co m } } } class MyThreadGroup extends ThreadGroup { public MyThreadGroup(String name) { super(name); } @Override public void uncaughtException(Thread t, Throwable e) { // Prints the name of the Thread System.out.printf("The thread %s has thrown an Exception\n", t.getId()); // Print the stack trace of the exception e.printStackTrace(System.out); // Interrupt the rest of the threads of the thread group System.out.printf("Terminating the rest of the Threads\n"); interrupt(); } } class Task implements Runnable { @Override public void run() { while (true) { Integer.parseInt("DEMO2s.com"); // Check if the Thread has been interrupted if (Thread.currentThread().isInterrupted()) { System.out.printf("%d : Interrupted\n", Thread.currentThread().getId()); return; } } } }