Starting a new thread on Exception using Uncaught Exceptional Handler

1k views Asked by At

A runnable task parses incoming xml file and is invoked from a different class. Sometimes the parsing may fail and throw an exception. The task should be running even when exceptions occur. I tried restarting the same task in a new thread using Uncaught exception handler. But wanted more ideas on that.

Class invoking thread : (invokes thread)

It works fine to restart same task in new thread but probably handling exceptions without leading to a thread exit should be the way

    Thread fileProcessThread = new Thread(FileProcessor);

    fileProcessorThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
          {
             @Override
             public void uncaughtException (Thread arg0, Throwable arg1)
              {
                FileProcessor newObject = new FileProcessorTask();
                Thread t = new Thread(newObject);
                t.start();
              }
          });

    fileProcessor.start();

Task Class :

      public void run() {

        try {
              xmlparser.parse(incomingXmlFile);
            } 
            catch (Exception e) {
                Thread.currentThread.getUncaughtExceptionalHandler().uncaughtException(Thread.currentThread(), e); 
                // this invokes uncaughtException to restart thread ?
            }
      }

I have a watch service (file directory scan) running, so I need the task all the time, even if thread terminates.

1

There are 1 answers

0
Kishore Bandi On BEST ANSWER

When an exception occurs and call reaches the uncaughtExceptionHandler, the state of the thread is Invalid to start again. So you need to create a new thread and start again.

Code from Thread.start()

// A zero status value corresponds to state "NEW".
if (threadStatus != 0)
   throw new IllegalThreadStateException();

However this could easily result in an infinite loop. (exception -> catch -> retry -> exception -> catch ...) I recommend having a counter which stops the retries after a certain point.

Public class TestClass{
    static AtomicInteger counter = new AtomicInteger();

    static class MyExceptionHandler implements UncaughtExceptionHandler {
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            System.out.println("caught");
            if (counter.get() == 3) {
                System.out.println("Reached Max. retries, exiting");
            } else {
                counter.incrementAndGet();
                new Thread(new MyTask()).start();
            }

        }
    }

    static class MyTask implements Runnable {
        @Override
        public void run() {
            try {
                Thread.currentThread().setUncaughtExceptionHandler(new MyExceptionHandler());
                System.out.println("slept");
                Thread.sleep(500);
                double d = 0 / 0;
            } catch (InterruptedException e) {}
        }
    }

    public static void main(String args[]) throws Exception {
        Thread thread = new Thread(new MyTask());
        thread.start();
    }
}

I've used static AtomicInteger but in your implementation probably have a common object which can be passed on from one thread to another and let that object have a counter.