Wednesday, 16 November 2016

Catching Child thread class exceptions in Main thread class and vice-versa in java

I came across a situation where we need to handle child thread class exceptions in main  thread class. Means which exception child class is throwing that to be handled by Main class.

Hope Most of the experience Java guys know this. This question normally asked in interview questions for experience people. I too came across this same question in one of my interview. That’s why I am sharing this program in my blog. Hope those who visit my page get benefit of it.

I have written two programs for this using.

  • UncaughtExceptionHandler
  • Executors Framework


Using UncaughtExceptionHandler: 

In this program I have used java 8 Lambda expression. If you not familiar with Java 8, you can comment java8 line and uncomment the java7 code.


import java.lang.Thread.UncaughtExceptionHandler;

/**
 * @author Bipin
 * This demonstrates how Main thread can see and print the exceptions generated by child thread
 *
 */
public class ChildThreadThrowingException {
       public static void main(String... args) {
            
             System.out.println("Main Thread");
             MyThread t = new MyThread();
            
// functional interface
   /*
   UncaughtExceptionHandler h = new UncaughtExceptionHandler()                                         {                          
              
                    @Override
                    public void uncaughtException(Thread thread, Throwable throwable) {
                           System.out.println(throwable);
                          
                    }
             };
             */
            
             
             // Using Java 8
      //UncaughtExceptionHandler h = (Thread thread, Throwable throwable) -> System.out.println(throwable);
            
//More advantage of Java 8             
       UncaughtExceptionHandler h = (thread, throwable) -> System.out.println(throwable);
            
             t.start();
             t.setUncaughtExceptionHandler(h);
            
       }
}

class MyThread extends Thread {
      
       private int x;

       public void run() {
             System.out.println("Child Thread");
             try {
                    x = 9/0;
                    System.out.println(x);
             }
             catch(ArithmeticException e) {
                    throw new ArithmeticException("Divide By Zero");
             }
            
       }
}

o/p:
Main Thread
Child Thread
java.lang.ArithmeticException: Divide By Zero


Using Executors Framework

import java.io.IOException;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/*
 * This class is going to use ExcecutorService and Future to handle the Exception
 */
public class MyExecutorService {

      
       public static void main(String[] args) {
            
             System.out.println("Main Thread");
            
             //Creates a thread pool that creates new threads as needed,
             //but will reuse previously constructed threads when they are available.
             ExecutorService executor = Executors.newCachedThreadPool();
            
             //Get the return object and used get() method that can wait for
             //the Callable to finish and then return the result.
             Future<Integer> future = executor.submit(new Callable<Integer>() {
                    /*                 
                     * Call method can either return a value or exception
                     */
                    @Override
                    public Integer call() throws Exception {
                          
                           Random randomnew Random();
                           int duration = random.nextInt(4000);
                          
                           if(duration > 2000) {
                                 throw new IOException("Sleep for "+duration+" miliseconds. Too much to sleep");
                           }
                          
                           System.out.println("Child Thread Starting");
                          
                           Thread.sleep(duration);
                          
                           System.out.println("Child Thread finished");
                          
                           return duration;
                    }
             });
            
             executor.shutdown();
            
             try {
                   
                    //Print the future result
                    System.out.println(future.get());
                   
             } catch (InterruptedException | ExecutionException e) {
                   
                    //Print the exception message that is set in call()
                    //System.out.println(e.getCause().getMessage()); //o/p: Sleep for 2766 miliseconds. Too much to sleep
                   
                    System.out.println(e.getMessage()); //o/p: java.io.IOException: Sleep for 2173 miliseconds. Too much to sleep
             }
       }

}


The End. Happy Codding. J

Thanks

Bipin

1 comment: