Exception Handling in Threads
Java
#java
#threads
By contract, Runnable#run method does not allow throwing exceptions . Possible ways of handling exceptions are try/catch blocks
or setting exception handler
on thread or thread group.
A thread or thread group allows us to set an exception handler on it, to receive exceptions occured during the execution of thread.
How it works
If you are clever enough, following flowchart says it all. Have a look!
<span>thread running</span> start exception occurs UncaughtExceptionHandler
set on thread?
[Not supported by viewer] call uncaughtException
(Thread, Throwable)
[Not supported by viewer] end Yes No call uncaughtException
(Thread, Throwable)
in thread group
[Not supported by viewer] is there any parent
thread group?
[Not supported by viewer] Yes is
DefaultUncaughtExceptionHandler
set on thread?
[Not supported by viewer] No call it with exception and thread as arg
call it with exception and thread as arg Yes end print stacktrace to
error stream and
terminate thread
[Not supported by viewer] No
Example
Create a general ExceptionalThread
class which inherits from Thread
and generates ArrayIndexOutOfBoundsException
when run. See the code below
class ExceptionalThread extends Thread {
ExceptionalThread ( String name ) {
super ( name );
}
ExceptionalThread ( ThreadGroup group , String name ) {
super ( group , name );
}
@Override
public void run () {
super . run ();
// generates ArrayIndexOutOfBoundsException
final int unused = ( new int [ 2 ])[ 3 ];
System . out . println ( unused );
} // run
} // ExceptionalThread
Inherit 3 more classes from this class with names DefaultHandler
, ThreadGroupHandler
, ThreadSpecificHandler
.
ThreadSpecificHandler
thread sets its UncaughtExceptionHandler
and exception will be caught in this handler.
ThreadGroupHandler
thread calls uncaughtException
method of its thread group.
DefaultHandler
thread calls DefaultUncaughtExceptionHandler
of the thread.
Code for all three classes is given below
ThreadSpecificHandler
class ThreadSpecificHandler extends ExceptionalThread {
ThreadSpecificHandler () {
super ( "ThreadSpecificHandler" );
}
} // ThreadSpecificHandler
ThreadGroupHandler
class ThreadGroupHandler extends ExceptionalThread {
ThreadGroupHandler ( ThreadGroup tg ) {
super ( tg , "ThreadGroupHandler" );
}
} // ThreadGroupHandler
DefaultHandler
class DefaultHandler extends ExceptionalThread {
DefaultHandler () {
super ( "DefaultHandler" );
}
@Override
public void run () {
Thread . setDefaultUncaughtExceptionHandler (( t , e ) -> App . exceptionHandler ( t , e , "Thread#UncaughtExceptionHandler (Default)" ));
super . run ();
}
} // DefaultHandler
App
public class App {
static void exceptionHandler ( Thread t , Throwable exp , String method ){
System . out . println ( String . format ( "Method: %s - ThreadName: %s - Exception: %s" , method , t . getName (), exp . getClass (). getSimpleName ()));
} // exceptionHandler
public static void main ( String [] args ) throws InterruptedException {
Thread threadWithHandler = new ThreadSpecificHandler ();
threadWithHandler . setUncaughtExceptionHandler (( t , e ) -> exceptionHandler ( t , e , "Thread#UncaughtExceptionHandler" ));
threadWithHandler . start ();
/* ------------------- THREAD GROUP ---------------*/
ThreadGroup group = new ThreadGroup ( "exp" ){
@Override
public void uncaughtException ( Thread t , Throwable e ) {
exceptionHandler ( t , e , "ThreadGroup#uncaughtException" );
}
};
/* ------------------- THREAD GROUP ---------------*/
Thread threadWithGroupHandler = new ThreadGroupHandler ( group );
threadWithGroupHandler . start ();
Thread threadWithDefaultHandler = new DefaultHandler ();
threadWithDefaultHandler . start ();
// wait for threads
threadWithDefaultHandler . join ();
threadWithGroupHandler . join ();
threadWithHandler . join ();
} // main
} // App
Output
Method: ThreadGroup#uncaughtException - ThreadName: ThreadGroupHandler - Exception: ArrayIndexOutOfBoundsException
Method: Thread#UncaughtExceptionHandler (Default) - ThreadName: DefaultHandler - Exception: ArrayIndexOutOfBoundsException
Method: Thread#UncaughtExceptionHandler - ThreadName: ThreadSpecificHandler - Exception: ArrayIndexOutOfBoundsException