How to handle exceptions in thread environment in Java?

exception-handlingExceptions handling of single-threaded and multi-threaded programs are different from each other. When single-threaded program terminates due to uncaught exception, it stop running and print exception stack trace on console. In other hand, when multi-threaded program encounter with uncaught exception, the stack trace may be printed, but no one may be watch that console. Because when that thread fail, application may appear continuously working. Therefore, there might be change that its failure may go unnoticed.

Exception is an unavoidable conditions, which can be occur in program due to lots of reasons. In threading application, we write our task in run() method of Thread class or Runnable interface. As you know run() method is an overridden method, that is why we can not throw any exception from run() method. Therefore all exceptions must be handle in side that run() method. Most of time we used methods of other classes as task in our run() method. In that case we would only aware about checked exceptions which are declared with signature of any methods. But there might be change that any method can throw RuntimeException. Any poor written code can throw NullPointerException from inside the method. These type of tasks should be call with in try and catch block that catch unchecked exceptions or with in try and finally block to ensure that if the thread exits abnormally the program is informed of this and can take corrective action.

There are two way to handle exceptions in Java threads. One is already mentioned above, with try, catch and finally block. Here is an example of same case. In this coding example you can see how to handle exception in thread and how to write recovery procedure for that.

public class ThreadManager extends Thread{

	@Override
	public void run() {
		Throwable thrown = null;
		try {
			while (!isInterrupted())
				// Run tasks until there is no task in Work Queue.
				runTask(getTaskFromWorkQueue());
		} catch (Throwable ex) {
			thrown = ex;
		} finally {
			// threadExited() method is recovery procedure 
			//if any exception occurs.  
			threadExited(this, thrown);
		}
	}

	public static void main(String[] args) {
		ThreadManager threadManager = new ThreadManager();
		threadManager.start();
	}

}

Above mentioned approach is proactive approach to the problem of unchecked exceptions. Where as Thread class it self provide UncaughtExceptionHandler facility. This handler let us detect when a thread dies due to an uncaught exception. Thread class has exposed and interface Thread.UncaughtExceptionHandler. We can implement this interface and set this implementation to any thread  Thread.setUncaughtExceptionHandler( UncaughtExceptionHandler eh ), so that thread can call that implementation, if any uncaught exception raise.

If we are not able to set exception handler to a particular  thread (For example, we are not able to create thread in thread pools), then you can set a default handler to thread with static method of thread Thread.setDefaultUncaughtExceptionHandler( UncaughtExceptionHandler eh ) .

Let me show you an coding example for both, to set an exception handler on particular thread and default exception handler using thread pool.

ExceptionThrowerRunnable.java

package com.hawk.java.thread;

/**
 * Demonstrates exceptions occurring inside a thread.
 *
 * @author SoManyWord.com
 */
public class ExceptionThrowerRunnable implements Runnable {

	public void run() {
		// This task will always throw an IllegalStateException
		throw new IllegalStateException("Running this is never legal.");
	}

}

LoggingThreadExceptionHandler.java

package com.hawk.java.thread;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Handle exceptions uncaught in threads by logging them.
 * @author SoManyWord.com
 */
public class LoggingThreadExceptionHandler implements Thread.UncaughtExceptionHandler {

	private Logger logger = Logger.getLogger("MYLOGGER");

	public void uncaughtException(Thread t, Throwable e) {
		logger.log(Level.ALL, "Error { "+ e +" } in Thread { "+ t +" } was uncaught.");
		e.printStackTrace();
	}
}

ThreadRunner.java

This class has set uncaught exception handler on particular thread.

package com.hawk.java.thread;

/**
 * Execute the threading application to demonstrate exception handling.
 * @author SoManyWord.com
 */
public class ThreadRunner {

	/**
	 * Start the application.
	 *
	 */
	public static void main(String[] args) {

		Thread thread = new Thread(new ExceptionThrowerRunnable());
		thread.setUncaughtExceptionHandler(new LoggingThreadExceptionHandler());
		thread.start();
	}
}

PoolRunner.java

If threads are running inside thread-pools then it is quite difficult to handle exception of each thread running inside thread-pool. Therefore, java.lang.Thread has provided a static method setDefaultUncaughtExceptionHandler() which takes java.lang.Thread.UncaughtExceptionHandler as an argument. By setting a default handler with this static method, you can set a default handler for all threads. This class sets a default uncaught exception handler on threads, which can catch any exception thrown inside thread pool.

package com.hawk.java.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Execute the tasks using thread pools.
 * @author SoManyWord.com
 *
 */
public class PoolRunner {

	/**
	 * Execute the {@link ExceptionThrowerRunnable} a couple of times in a pool.
	 */
	public static void main(String[] args) {
		// Set the default uncaught exception handler, 
                // If you are not able to set handler to a particular thread. 
		Thread.setDefaultUncaughtExceptionHandler(new LoggingThreadExceptionHandler());

		ExecutorService pool = Executors.newFixedThreadPool(2);

		Runnable r = new ExceptionThrowerRunnable();

		for(int i = 0; i < 10; i++) {
			pool.execute(r);
		}
	}
}

Now you know how to handle uncaught exceptions in thread environment. Either you could set handler on particular thread or you could set default handler as well. This default handler will be call if no other handler is set on thread. Hope this blog will help you to write robust code in multi-threading environment.

Deals on Tablets, Get up to 25% off on Tablets - Dell, Lenovo, Samsung, HCL and others.

One thought on “How to handle exceptions in thread environment in Java?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>