どの場合にfuture.get()スローexecutionExceptionまたはarturnedexception
-
27-09-2019 - |
質問
私のコードスニペット:
ExecutorService executor = Executors.newSingleThreadExecutor();
try {
Task t = new Task(response,inputToPass,pTypes,unit.getInstance(),methodName,unit.getUnitKey());
Future<SCCallOutResponse> fut = executor.submit(t);
response = fut.get(unit.getTimeOut(),TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
// if the task is still running, a TimeOutException will occur while fut.get()
cat.error("Unit " + unit.getUnitKey() + " Timed Out");
response.setVote(SCCallOutConsts.TIMEOUT);
} catch (InterruptedException e) {
cat.error(e);
} catch (ExecutionException e) {
cat.error(e);
} finally {
executor.shutdown();
}
どのように処理すればよいですか InterruptedException
と ExecutionException
コードで?
そして、どの場合に、これらの例外は投げられますか?
解決
ExecutionException
と InterruptedException
2つの非常に異なるものです。
ExecutionException
実行されているスレッドが投げた例外をラップするので、たとえばスレッドが何らかのIOを行うと、 IOException
投げられるために、それは ExecutionException
そしてrethrown。
an InterruptedException
何かが間違っていることの兆候ではありません。彼らが現在の作業を終えて優雅に出ることができるように、あなたのスレッドに停止する時間を知らせる方法をあなたに与えるためにそこにあります。アプリケーションに実行を停止させたいと言ってください。しかし、私のスレッドが何かの真ん中でしていることをドロップしたくないとします(これは、デーモンスレッドを作った場合に起こります)。そのため、アプリケーションがシャットダウンされている場合、私のコードはこれらのスレッドの割り込みメソッドを呼び出します。これにより、割り込みフラグが設定され、次にそれらのスレッドが待機または睡眠をとったときに割り込みフラグをチェックしてスローします。 InterruptedException
, 、これを使用して、スレッドが従事しているインフィニットループ処理/睡眠ロジックから救済することができます。(そして、スレッドが待っていない場合は、定期的に割り込みフラグを確認できます)。論理フローを変更するために使用される例外の。まったくログに記録する唯一の理由は、何が起こっているのか、または割り込みロジックが正しく機能していない問題をデバッグしている場合に、例プログラムに記録することです。
他のヒント
InterruptedException
場合は投げられます interrupt
計算が完了する前に、待機スレッドで呼び出されます。
ExecutionException
計算が関与するとスローされます(Task
この場合、例外自体をスローします。
これをどのように処理したいかは、アプリケーションに完全に依存します。
編集:中断されることのデモンストレーションは次のとおりです。
import java.util.concurrent.*;
public class Test
{
public static void main(String[] args) throws Exception
{
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<String> future = executor.submit(new SlowCallable());
executor.submit(new Interruptor(Thread.currentThread()));
try
{
System.out.println(future.get());
}
catch (InterruptedException e)
{
System.out.println("I was interrupted");
}
}
private static class Interruptor implements Callable<String>
{
private final Thread threadToInterrupt;
Interruptor(Thread threadToInterrupt)
{
this.threadToInterrupt = threadToInterrupt;
}
public String call() throws Exception
{
Thread.sleep(2000);
threadToInterrupt.interrupt();
return "interrupted other thread";
}
}
private static class SlowCallable implements Callable<String>
{
public String call() throws Exception
{
Thread.sleep(5000);
return "finished";
}
}
}
IBM Developer Worksの記事 中断exceptionを扱う 処理方法についてアドバイスがあります InterruptedException
.
3種類の例外を返すためのサンプルコード。
import java.util.concurrent.*;
import java.util.*;
public class ExceptionDemo{
public static void main(String args[]){
int poolSize=1;
int maxPoolSize=1;
int queueSize=30;
long aliveTive=60;
ArrayBlockingQueue<Runnable> queue= new ArrayBlockingQueue<Runnable>(queueSize);
ThreadPoolExecutor executor= new ThreadPoolExecutor(poolSize,maxPoolSize,aliveTive,
TimeUnit.MILLISECONDS,queue);
List<Future> futures = new ArrayList<Future>();
for ( int i=0; i < 5; i++){
futures.add(executor.submit(new RunnableEx()));
}
for ( Iterator it = futures.iterator(); it.hasNext();){
try {
Future f = (Future)it.next();
f.get(4000,TimeUnit.MILLISECONDS);
}catch(TimeoutException terr){
System.out.println("Timeout exception");
terr.printStackTrace();
}
catch(InterruptedException ierr){
System.out.println("Interrupted exception:");
ierr.printStackTrace();
}catch(ExecutionException err){
System.out.println("Exeuction exception:");
err.printStackTrace();
Thread.currentThread().interrupt();
}
}
executor.shutdown();
}
}
class RunnableEx implements Runnable{
public void run() {
// code in here
System.out.println("Thread name:"+Thread.currentThread().getName());
try{
Random r = new Random();
if (r.nextInt(2) == 1){
Thread.sleep(2000);
}else{
Thread.sleep(4000);
}
System.out.println("eee:"+1/0);
}catch(InterruptedException irr){
irr.printStackTrace();
}
}
}
出力:
Thread name:pool-1-thread-1
Timeout exception
Thread name:pool-1-thread-1
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask.get(FutureTask.java:201)
at ExceptionDemo.main(ExceptionDemo.java:20)
Thread name:pool-1-thread-1
Exeuction exception:
java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:202)
at ExceptionDemo.main(ExceptionDemo.java:20)
Caused by: java.lang.ArithmeticException: / by zero
at RunnableEx.run(ExceptionDemo.java:49)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Interrupted exception:
java.lang.InterruptedException
at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:400)
at java.util.concurrent.FutureTask.get(FutureTask.java:199)
at ExceptionDemo.main(ExceptionDemo.java:20)
Timeout exception
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask.get(FutureTask.java:201)
Thread name:pool-1-thread-1
at ExceptionDemo.main(ExceptionDemo.java:20)
Thread name:pool-1-thread-1
Timeout exception
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask.get(FutureTask.java:201)
at ExceptionDemo.main(ExceptionDemo.java:20)
Timeoutexception :ブロッキング操作がタイムアウトすると、例外がスローされます。
上記の例では、一部のタスクはより多くの時間をかけて(睡眠4秒のため)操作をブロックしています get()
の上 Future
タイムアウトを増やすか、実行可能なタスクを最適化します。
ExecutionException: :例外をスローすることで中止されたタスクの結果を取得しようとするときにスローされた例外=>計算は例外を投げました
上記の例では、これ Exception
介してシミュレートされます ArithmeticException: / by zero
一般に、例で引用されているように些細なことである場合、根本原因を修正する必要があります。
中断exception: :スレッドが待っている、睡眠、またはその他の方法で占有されているときに投げられ、アクティビティの前またはアクティビティ中に糸が中断されます。
上記の例では、これ Exception
中に電流スレッドを中断することによりシミュレートされます ExecutionException
.
一般的に、あなたはそれに基づいて行動しないことを捕らえる必要があります。