簡體   English   中英

使用未捕獲的異常處理程序在Exception上啟動新線程

[英]Starting a new thread on Exception using Uncaught Exceptional Handler

可運行任務解析傳入的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 ?
            }
      }

我正在運行監視服務(文件目錄掃描),因此即使線程終止,我也始終需要執行任務。

當發生異常並且調用到達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但是在您的實現中可能有一個公共對象,該對象可以從一個線程傳遞到另一個線程,並讓該對象具有計數器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM