キャッチされない例外ハンドラ
スレッドの run メソッドはチェック済み例外をスローできませんが、チェックされていない例外によってスレッドが終了する可能性があり、この場合、スレッドは停止し、メイン スレッドも異常終了します。。
伝播可能な例外の場合、スレッドが終了する前に、例外はキャッチされなかった例外のハンドラーに渡されます。前提として、プロセッサはThread.UncaughtExceptionHandler
インターフェイスを実装するクラスである必要があります。。
これらの言葉は何を意味するのでしょうか? 続きを読んでください。
以下のように、runメソッドで強制的に例外をスローするとエラーが報告されます。
したがって、スレッド内で例外が発生した場合、try-catch
可能な限り例外をキャッチすることしかできません。
しかし、各スレッドの 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
エラーが発生していますが、これはチェックされていない例外であるため、コード ブロックでラップしませんでした。ただし、コードが未チェック例外をスローすると、他のスレッドでそれをキャッチすることはできません。そのため、メインスレッドでチェックされていない例外をキャッチしようとしましたが、キャッチできず、最終的にプログラムは例外により終了しなければなりませんでした。通常は、以下を参照してください。ArithmeticException
try-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.UncaughtExceptionHandler
、uncaughtException
このメソッド内で例外の処理を定義しました。その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