使用Uncaught Exceptional Handler在Exception上启动一个新线程

时间:2017-01-09 19:46:27

标签: java multithreading exception exception-handling uncaughtexceptionhandler

runnable任务解析传入的xml文件,并从另一个类调用。有时解析可能会失败并抛出异常。即使发生异常,任务也应该运行。我尝试使用Uncaught异常处理程序在新线程中重新启动相同的任务。但是想要更多的想法。

类调用线程:(调用线程)

在新线程中重启同样的任务可以正常工作但是可能处理异常而不会导致线程退出

    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();

任务类:

      public void run() {

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

我有一个运行的监视服务(文件目录扫描),所以即使线程终止,我也一直需要该任务。

1 个答案:

答案 0 :(得分:1)

当发生异常并且调用到达uncaughtExceptionHandler时,线程的状态为Invalid以再次启动。因此,您需要创建一个新线程并重新开始。

来自 Thread.start()

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

然而,这很容易导致无限循环。 (例外 - > catch - >重试 - >例外 - > catch ...) 我建议有一个计数器,在某一点之后停止重试。

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();
    }
}

我已经使用过static AtomicInteger但是在你的实现中可能有一个公共对象,可以从一个线程传递到另一个线程,并让该对象有一个计数器。