マイナー・マイナー

隠れた名作の発掘が生きがい。

スレッドがスローする例外をキャッチする


スポンサードリンク

マルチスレッド環境下で,あるスレッドからスローした例外を別のスレッドでキャッチしたい場合,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

うまく使えばスレッド間でデータの受け渡しをすることもできたりするかもしれないです.