2005.10.17 株式会社四次元データ 宮澤了祐
マルチスレッドプログラミング 6章 スレッドクラスの変更点
- 6.1. Threadクラスの変更点
- 6.2. スタックトレースの取得
- 6.3. キャッチされない例外の取得
- 6.4. スレッドの状態の取得
- 6.5. 一ミリ秒未満のスリープ
6.3. キャッチされない例外の取得
例として以下のソースを見てください。
public class ThreadSample implements Runnable { public static void main(String[] args) { Thread thread = new Thread(new ThreadSample()); thread.start(); while(true){ try { Thread.sleep(100L); } catch (InterruptedException e) { e.printStackTrace(); } } } public void run() { throw new RuntimeException(); } }
ThreadSampleクラスでは、通常キャッチする必要のないRuntimeExceptionを投げています。 例外が発生しても、プログラムは動作し続けてしまいます。 本来ならばスレッドを再び起動するなどの処理を行うべき箇所です。
「java.lang.Thread.UncaughtExceptionHandler」インタフェースは、 「java.lang.ThreadGroup」のuncaughtException()メソッドをインタフェース化したものです。 UncaughtExceptionHandlerは、キャッチされない例外によって指定されたスレッドが終了したときに呼び出される、 uncaughtException()メソッドのみを持つインタフェースです。 ThreadGroupを作成するより、簡単に例外を取得出来ます。
ThreadGroupを作成する方法
ThreadGroup group = new ThreadGroup("group"){ public void uncaughtException(Thread t,Throwable e) { e.printStackTrace(); } }; Thread thread = new Thread(group,new ThreadSample()); thread.start();
このように、ThreadGroupを作成し、uncaughtException()メソッドをオーバーライドする必要がありました。 JDK1.5よりこのuncaughtException()メソッドがインタフェース化し、ThreadGroupを作成せずにすむようになりました。
Thread.UncaughtExceptionHandlerを実装したハンドラを、 ThreadのsetUncaughtExceptionHandler()メソッドで登録します。
public void ThreadSample implements Runnable{ public static void main(String[] args) { Thread thread = new Thread(new ThreadSample()); thread.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler()); ... }
import java.lang.Thread.UncaughtExceptionHandler; public class MyUncaughtExceptionHandler implements UncaughtExceptionHandler { public void uncaughtException(Thread thread, Throwable throwable) { //アプリケーションの終了 System.out.println("例外が発生しました。"); throwable.printStackTrace(); System.out.println("スレッドを再起動します。"); thread.start(); } }
ここではスタックトレースを出力した上で、スレッドの再起動を行っています。 このサンプルは次のように出力されます。
例外が発生しました。 java.lang.RuntimeException at ThreadSample.run(ThreadSample.java:41) at java.lang.Thread.run(Unknown Source) スレッドを再起動します。 ...