UncaughtExceptionHandlerの機能と簡単な使い方

キャッチされない例外ハンドラ

スレッドの run メソッドはチェック済み例外をスローできませんが、チェックされていない例外によってスレッドが終了する可能性があり、この場合、スレッドは停止し、メイン スレッドも異常終了します。

伝播可能な例外の場合、スレッドが終了する前に、例外はキャッチされなかった例外のハンドラーに渡されます。前提として、プロセッサはThread.UncaughtExceptionHandlerインターフェイスを実装するクラスである必要があります。

これらの言葉は何を意味するのでしょうか? 続きを読んでください。

以下のように、runメソッドで強制的に例外をスローするとエラーが報告されます。

画像-20201218225951286

したがって、スレッド内で例外が発生した場合、try-catch可能な限り例外をキャッチすることしかできません。

画像-20201218225951286

しかし、各スレッドの run メソッドでは、コードのすべての文を大きなコード ブロックにラップすることは不可能ですtry-catchチェック例外は try-catch コード ブロックでラップする必要がありますが、未チェック例外も多数あります。未チェック例外が問題を起こさないことは保証できませんが、すべての未チェック例外をラップするのtry-catchは適切ではありません。

以下のコードを参照してください。

コードの最初の部分:

package concurrence;

public class UncaughtExceptionHandlerTest {
    
    
  public static void main(String[] args) throws InterruptedException {
    
    
    try {
    
    
      Thread thread1 = new Thread(new MyRunnable());
      thread1.start();
    } catch (Exception ex) {
    
    
      System.out.println("Exception:" + ex.getMessage());
    }
  }
}

class MyRunnable implements Runnable {
    
    
  @Override
  public void run() {
    
    
    System.out.println(2 / 1);
    System.out.println(2 / 0);
    System.out.println(2 / 2);
  }
}

thread1 の run メソッドで例外である2/0エラーが発生していますが、これはチェックされていない例外であるため、コード ブロックでラップしませんでした。ただし、コードが未チェック例外をスローすると、他のスレッドでそれをキャッチすることはできません。そのため、メインスレッドでチェックされていない例外をキャッチしようとしましたが、キャッチできず、最終的にプログラムは例外により終了しなければなりませんでした。通常は、以下を参照してください。ArithmeticExceptiontry-catch
ここに画像の説明を挿入

2 番目のコード部分:

package concurrence;

public class Test {
    
    
  public static void main(String[] args) {
    
    
    try {
    
    
      dividByZero();
    } catch (Exception ex) {
    
    
      System.out.println("Exception:" + ex);
    }
  }

  public static void dividByZero() {
    
    
    System.out.println(2 / 1);
    System.out.println(2 / 0);
    System.out.println(2 / 2);
  }
}

通常の状況では、チェックされていない例外をキャッチできるため、プログラムが例外によって終了することはありません。
ここに画像の説明を挿入
しかし現在、マルチスレッドではrun メソッドで未チェックの例外をキャッチできません。runこれは、メソッド内のコード ブロック未チェックの例外をtry- catchキャッチしない場合、例外が原因でプログラムが終了するという意味ですか?

もちろんそうではなく、この時点でUncaughtExceptionHandlerデビューできます。

伝播可能な例外の場合、スレッドが終了する前に、例外はキャッチされなかった例外のハンドラーに渡されます。前提として、プロセッサはThread.UncaughtExceptionHandlerインターフェイスを実装するクラスである必要があります。

そこで、MyUncaughtExceptionHandlerクラス内のメソッドを書き直しThread.UncaughtExceptionHandleruncaughtExceptionこのメソッド内で例外の処理を定義しました。そのthread1 start前に、setUncaughtExceptionHandlerメソッドを使用してスレッドを設定します。

3 番目のコード部分:

package concurrence;

public class UncaughtExceptionHandlerTest {
    
    
  public static void main(String[] args) throws InterruptedException {
    
    
    try {
    
    
      Thread thread1 = new Thread(new MyRunnable());
      thread1.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
      thread1.start();
    } catch (Exception ex) {
    
    
      System.out.println("Exception:" + ex.getMessage());
    }
  }
}

class MyRunnable implements Runnable {
    
    
  @Override
  public void run() {
    
    
    System.out.println(2 / 1);
    System.out.println(2 / 0);
    System.out.println(2 / 2);
  }
}

class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
    
    
  @Override
  public void uncaughtException(Thread t, Throwable e) {
    
    
    System.out.println(t.getName() + " " + e.getMessage());
  }
}

こうすることで、 run メソッドで未チェックの例外が発生した場合、 thread1 が終了する前にメインスレッドで例外をキャッチできるため、メインプログラムも正常に終了でき、例外が原因で終了することはありません。 。
ここに画像の説明を挿入

転載:https://blog.csdn.net/qq_42799615/article/details/111658473

おすすめ

転載: blog.csdn.net/gqg_guan/article/details/132326136