マルチスレッド環境下で,あるスレッドからスローした例外を別のスレッドでキャッチしたい場合,java.lang.Thread.UncaughtExceptionHandlerインタフェースを実装したクラスを用意し,このインスタンスを例外がスローされるスレッドにセットするということをします.
具体的には次の手順でスレッドがスローした例外をキャッチできます.
1. UncaughtExceptionHandlerインタフェースを実装したクラスAの用意
UncaughtExceptionHandlerインタフェースを実装したクラスを用意します.そのインタフェースには次のメソッドが記述されています.
public void uncaughtException(Thread t, Throwable e)
これは,スレッドからスローされた例外をキャッチするメソッドですので,例外キャッチ時に処理したい内容を記述します.引数には例外の送出元スレッドと例外インスタンスを取ります.
2. 例外がスローされるスレッドをインスタンス化し,それにAのインスタンスをセット
まず,スレッドをインスタンス化します(このスレッドをthreadとします).そして,thread.setUncaughtExceptionHandlerメソッドを呼び出し,そのメソッドにAのインスタンスを引数として与えます.
3. 例外発生時の処理
threadでエラーがスローされたとき,そのエラーはAのインスタンスでキャッチされ,uncaughtExceptionメソッドが呼び出されます.このメソッドの引数に,例外がスローされたスレッドと例外インスタンスが与えられます.
スレッドがスローした例外をキャッチするプログラムを以下のように作成しました.スレッドを10個生成し,ランダムな時間で例外を発生させます.これらのスレッドにはUncaughtExceptionHandlerを実装したクラスCatchExceptionのインスタンスがsetUncaughtExceptionHandlerによってセットされています.そして,例外が発生したとき,CatchExceptionのuncaughtExceptionメソッドで例外が発生したスレッド名を表示します.
import java.lang.Thread.UncaughtExceptionHandler; class ThrowException implements Runnable { public void run() { try { Thread.sleep((long) Math.random()); throw new RuntimeException("RutimeException"); } catch (InterruptedException e) { } } } class CatchException implements UncaughtExceptionHandler { public void uncaughtException(Thread t, Throwable e) { System.out.println(t.getName()); } } public class ThreadExceptionTest { public static void main(String[] args) { CatchException catchException = new CatchException(); for (int i = 0; i < 10; i++) { Thread thread = new Thread(new ThrowException(), "Thread-" + i); thread.setUncaughtExceptionHandler(catchException); thread.start(); } } }
実行結果
Thread-0
Thread-2
Thread-4
Thread-6
Thread-8
Thread-1
Thread-3
Thread-5
Thread-7
Thread-9
うまく使えばスレッド間でデータの受け渡しをすることもできたりするかもしれないです.