- PR -

java.util.concurrentのScheduledExecutorタスクのエラーキャッチについて

1
投稿者投稿内容
ゆず
会議室デビュー日: 2005/11/29
投稿数: 3
投稿日時: 2005-11-29 13:20
はじめて書き込みします。
現在J2SE5.0でjava.util.concurrentを使用しています。

ScheduledExecutorServiceのタスク実行中のRuntimeExceptionを
キャッチできません。

newSingleThreadScheduledExecutor(threadFactory)にて
作成したスケジューラのタスクの
実行中のRuntimeExceptionなどを取得するために
UncaughtExceptionHandlerをthreadFactoryのnewThreadの中でセットしたのですが、
まったくキャッチされません。

調べたところ、戻り値のFutureのgetメソッド等にアクセスした時に、Thread実行時のExceptionが発生するようです。
runnableのrunメソッドで行うため戻り値を得ることができない状況なので
キャッチできないのですが、ThreadScheduledExecutor
でRuntimeExceptionをキャッチする方法は他にあるのでしょうか?

よろしくお願いします。
シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2005-11-29 13:31
>runnableのrunメソッドで行うため戻り値を得ることができない状況なので
>キャッチできないのですが、

試してもいないので、本当に出来るかわかりませんが、
Executors#callable(Runnable)でRunnableをラップしたらいかがでしょうか?
ゆず
会議室デビュー日: 2005/11/29
投稿数: 3
投稿日時: 2005-11-29 14:02

シュンさん、アドバイスありがとうございます。

callableにしてみようと思ったのですが、
scheduleAtFixedRate(Runnable command,long initialDelay,
long period, TimeUnit unit)
を使って繰り返し実行しているので、callableをセットできませんでした(T-T)

また、他のHPを調べたら以下のようなことが書いてありました↓
「どうやらCallableの場合は、戻り値のFutureのgetメソッド等にアクセスした時に、Thread実行時のExceptionが発生するようです。戻り値を取得する時に例外処理ができるので問題ないと思ってたんですが、問題あり。戻り値の型がvoidの場合は、Futureを取得できないので例外処理ができません。」

他に方法がないのであれば、
Runnableのrunメソッドのなかの実行コードを
try{}catch(Trowable t){}で囲むことで対応して
取り残しのExceptionなどはないと言って大丈夫なのでしょうか?
シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2005-11-29 17:24
コード:
package test;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ExecTest {
	
	static class TestCommand implements Runnable{
		public void run() {
			throw new RuntimeException("Test");
		}
	}
	
	
	public static void main(String args[])throws Exception{
		ScheduledThreadPoolExecutor ex  = new ScheduledThreadPoolExecutor(1);
		ScheduledFuture f = ex.schedule(new TestCommand(),10,TimeUnit.SECONDS);
		
		try{
			f.get();
		}
		catch(ExecutionException e){
			System.out.println(e.getCause());
		}
		
	}

}



ExecutionExceptionにラップされて返ってきてますよ。
これでは駄目なのでしょうか?
ゆず
会議室デビュー日: 2005/11/29
投稿数: 3
投稿日時: 2005-11-30 11:48
シュンさん調べていただいてありがとうございます。
私の書き方がわかりにくくてすいませんでした。

今回定期的にrunを実行するというex.scheduleAtFixedRateをつかっていますので、
f.get()を書いてしまいますと、正常系の処理の時に処理がこのgetから進まなく
なってしまうんです。

異常系の場合は取得できて処理は以降に進んでいくのですが。
f.get()の部分がなければスレッドは進んでmainに帰ってきます。

実際は、マスタースレッドからサブのスケジュールスレッド作成クラスを呼んでいます
ので、処理がマスターに戻らないと困るのです。

わかりにくい説明ですいません。よろしくお願いします。

<実行結果>
run
run
run
・・・・・・・・・
と永遠に出続ける。(aaaaは出力されない)

↓以下のプログラムを実行

public class ExecTest {
static class TestCommand implements Runnable{
public void run() {
System.out.println("run");
//throw new RuntimeException("Test");
}
}

public static void main(String args[])throws Exception{
ScheduledThreadPoolExecutor ex = new ScheduledThreadPoolExecutor(1);
ScheduledFuture f = ex.scheduleAtFixedRate(new TestCommand(),1,1,TimeUnit.SECONDS);
{
f.get();
}
catch(ExecutionException e){
System.out.println(e.getCause());
}
System.out.println("aaaa");
}
}

シュン
ぬし
会議室デビュー日: 2004/01/06
投稿数: 328
お住まい・勤務地: 東京都
投稿日時: 2005-12-01 23:29
結果を監視するのに1スレッド割り当てていただければよいとおもいますが…


コード:
package test;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ExecTest {
	
	static class TestCommand implements Runnable{
		public void run() {
			throw new RuntimeException("Test");
		}
	}
	
	
	public static void main(String args[])throws Exception{
		ScheduledThreadPoolExecutor ex  = new ScheduledThreadPoolExecutor(1);
		ScheduledFuture f = ex.schedule(new TestCommand(),10,TimeUnit.SECONDS);
		
		try{
			while(true)f.get();
		}
		catch(ExecutionException e){
			System.out.println(e.getCause());
		}
		
	}

}


1

スキルアップ/キャリアアップ(JOB@IT)