Javaサブスレッドによる異常処理方法(共通)
通常のシングルスレッドプログラムでは、異常を捕獲するにはtry...catch...finally...コードブロックだけでいいです。併発の場合、例えば親スレッドにおいて子スレッドが起動していますが、親スレッドに子スレッドからの異常がどのように捕獲され、対応する処理が行われますか?
よくあるエラー
簡単だと思う人もいるかもしれませんが、直接にスレッドを立てるところでtry...catchを使えばいいです。実はこれは違います。
原因分析
Runnableインターフェースのrunメソッドの完全な署名を思い出してみましょう。throws文が表示されていないので、方法はchecedを投げません。RuntimeExceptionのようなunchecked異常については、新しいスレッドはJVMでスケジュール実行されますので、異常が発生したら親スレッドにも通知されません。
public abstract void run()
解決策
では、親スレッドに子スレッドからの異常をどのように捉えますか?ビルの主人は3種類の常用方法を思い付いて、みんなに分かち合います。
方法1:子スレッド中try…catch…
最も簡単で効果的な方法は、子スレッドの方法で、異常が発生する可能性のあるところをtry...catch...という語句でくるむことです。サブスレッドコード:
スレッドに異常プロセッサを設定します。具体的なやり方は以下の通りです。
(1)Thread.set Unicaght Exception Handler現在のスレッドの異常プロセッサを設定する
(2)Thread.set Default UnicaghtException Handlerはプログラム全体にデフォルトの異常プロセッサを設定します。現在スレッドに異常プロセッサがある場合(デフォルトではない)、このUnicaghtException Handler類を優先的に使用します。そうでなければ、現在スレッドが属するスレッドグループに異常プロセッサがある場合は、スレッドグループのException Handlerを使用する。そうでなければ、グローバルデフォルトのDefault Uncaght Exception Handlerを使用します。全部ないと、子スレッドは終了します。
注意:サブスレッドに異常が発生しました。何かの種類がなければ、直接に終了します。ログを残して印刷しません。だから、何もしないと、サブスレッドのタスクは実行されていないし、ログのヒントもない「怪しい」現象が発生します。
現在のスレッドの異常プロセッサを設定します。
handle exception in child thread.java.lang.RuntimeException:Child Thread exception
方法三、Futureのget方法で異常を捕捉する。
スレッド池を使って返信情報を得る方法、つまりExectorService.submit(Callable)はsubmitの後にスレッド実行結果を得ることができるFutureオブジェクトを提出しますが、サブスレッドに異常が発生した場合は、future.get()を介して返却値を取得した場合は、Execution Exception Excetion異常を捕捉することができます。
サブスレッドコード:
handle exception in child thread.java.util.co ncurrent.Execution Exception:java.lang.RuntimeException:Child Thread 1 exception
締め括りをつける
上には三つのよく使われているJava子スレッドの異常処理方法があります。実はビル主はまたその他のいくつかの特定のシーンの下の解決方法を思い付いて、日を改めて更に分析して、みんなに支持されてありがとうございます。
このJava子スレッドにおける異常処理方法(共通)は、小編集が皆さんに提供しているすべての内容を共有しています。参考にしていただければと思います。どうぞよろしくお願いします。
よくあるエラー
簡単だと思う人もいるかもしれませんが、直接にスレッドを立てるところでtry...catchを使えばいいです。実はこれは違います。
原因分析
Runnableインターフェースのrunメソッドの完全な署名を思い出してみましょう。throws文が表示されていないので、方法はchecedを投げません。RuntimeExceptionのようなunchecked異常については、新しいスレッドはJVMでスケジュール実行されますので、異常が発生したら親スレッドにも通知されません。
public abstract void run()
解決策
では、親スレッドに子スレッドからの異常をどのように捉えますか?ビルの主人は3種類の常用方法を思い付いて、みんなに分かち合います。
方法1:子スレッド中try…catch…
最も簡単で効果的な方法は、子スレッドの方法で、異常が発生する可能性のあるところをtry...catch...という語句でくるむことです。サブスレッドコード:
public class ChildThread implements Runnable {
public void run() {
doSomething1();
try {
//
exceptionMethod();
} catch (Exception e) {
//
System.out.println(String.format("handle exception in child thread. %s", e));
}
doSomething2();
}
}
方法2:スレッドのための異常プロセッサユニットException Handlerを設定します。スレッドに異常プロセッサを設定します。具体的なやり方は以下の通りです。
(1)Thread.set Unicaght Exception Handler現在のスレッドの異常プロセッサを設定する
(2)Thread.set Default UnicaghtException Handlerはプログラム全体にデフォルトの異常プロセッサを設定します。現在スレッドに異常プロセッサがある場合(デフォルトではない)、このUnicaghtException Handler類を優先的に使用します。そうでなければ、現在スレッドが属するスレッドグループに異常プロセッサがある場合は、スレッドグループのException Handlerを使用する。そうでなければ、グローバルデフォルトのDefault Uncaght Exception Handlerを使用します。全部ないと、子スレッドは終了します。
注意:サブスレッドに異常が発生しました。何かの種類がなければ、直接に終了します。ログを残して印刷しません。だから、何もしないと、サブスレッドのタスクは実行されていないし、ログのヒントもない「怪しい」現象が発生します。
現在のスレッドの異常プロセッサを設定します。
public class ChildThread implements Runnable {
private static ChildThreadExceptionHandler exceptionHandler;
static {
exceptionHandler = new ChildThreadExceptionHandler();
}
public void run() {
Thread.currentThread().setUncaughtExceptionHandler(exceptionHandler);
System.out.println("do something 1");
exceptionMethod();
System.out.println("do something 2");
}
public static class ChildThreadExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
System.out.println(String.format("handle exception in child thread. %s", e));
}
}
}
または、すべてのスレッドのデフォルト異常プロセッサを設定します。
public class ChildThread implements Runnable {
private static ChildThreadExceptionHandler exceptionHandler;
static {
exceptionHandler = new ChildThreadExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(exceptionHandler);
}
public void run() {
System.out.println("do something 1");
exceptionMethod();
System.out.println("do something 2");
}
private void exceptionMethod() {
throw new RuntimeException("ChildThread exception");
}
public static class ChildThreadExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
System.out.println(String.format("handle exception in child thread. %s", e));
}
}
}
コマンドライン出力:ドsomething 1handle exception in child thread.java.lang.RuntimeException:Child Thread exception
方法三、Futureのget方法で異常を捕捉する。
スレッド池を使って返信情報を得る方法、つまりExectorService.submit(Callable)はsubmitの後にスレッド実行結果を得ることができるFutureオブジェクトを提出しますが、サブスレッドに異常が発生した場合は、future.get()を介して返却値を取得した場合は、Execution Exception Excetion異常を捕捉することができます。
サブスレッドコード:
public class ChildThread implements Callable {
public Object call() throws Exception {
System.out.println("do something 1");
exceptionMethod();
System.out.println("do something 2");
return null;
}
private void exceptionMethod() {
throw new RuntimeException("ChildThread1 exception");
}
}
親スレッドコード:
public class Main {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(8);
Future future = executorService.submit(new ChildThread());
try {
future.get();
} catch (InterruptedException e) {
System.out.println(String.format("handle exception in child thread. %s", e));
} catch (ExecutionException e) {
System.out.println(String.format("handle exception in child thread. %s", e));
} finally {
if (executorService != null) {
executorService.shutdown();
}
}
}
}
コマンドライン出力:ドsomething 1handle exception in child thread.java.util.co ncurrent.Execution Exception:java.lang.RuntimeException:Child Thread 1 exception
締め括りをつける
上には三つのよく使われているJava子スレッドの異常処理方法があります。実はビル主はまたその他のいくつかの特定のシーンの下の解決方法を思い付いて、日を改めて更に分析して、みんなに支持されてありがとうございます。
このJava子スレッドにおける異常処理方法(共通)は、小編集が皆さんに提供しているすべての内容を共有しています。参考にしていただければと思います。どうぞよろしくお願いします。