0

実行可能なタスクは、着信 xml ファイルを解析し、別のクラスから呼び出されます。場合によっては、解析が失敗して例外がスローされることがあります。例外が発生した場合でも、タスクは実行されている必要があります。Uncaught 例外ハンドラを使用して、新しいスレッドで同じタスクを再開しようとしました。しかし、それについてもっとアイデアが欲しかった。

Class invoking thread : (スレッドを呼び出す)

新しいスレッドで同じタスクを再起動することは問題なく機能しますが、おそらくスレッドの終了に至らずに例外を処理する方法が必要です

    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 ?
            }
      }

監視サービス (ファイル ディレクトリ スキャン) を実行しているので、スレッドが終了しても常にタスクが必要です。

4

1 に答える 1

1

例外が発生し、呼び出しが uncaughtExceptionHandler に到達すると、スレッドの状態は Invalid になり、再び開始されます。そのため、新しいスレッドを作成して、最初からやり直す必要があります。

Thread.start()からのコード

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

ただし、これは簡単に無限ループに陥る可能性があります。(例外 -> キャッチ -> 再試行 -> 例外 -> キャッチ ...) 特定の時点で再試行を停止するカウンターを用意することをお勧めします。

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たが、実装にはおそらく、あるスレッドから別のスレッドに渡すことができる共通のオブジェクトがあり、そのオブジェクトにカウンターを持たせることができます。

于 2017-01-09T20:53:29.003 に答える