2012-07-17 11 views
8

2つのタスクを完了してから結果を返すが、ときどきこのエラーが発生することがあります。どうして? CancellationExceptionはどこから来たのですか?ExecutorServiceを使用しているときにCancellationExceptionが発生する

public class ShouldVoteTask extends AbstractWorkerTask<Void, Void, Boolean> { 
    private final int placeID; 
    private final int userID; 

    public ShouldVoteTask(final int placeID, final int userID) { 
     this.placeID = placeID; 
     this.userID = userID; 
    } 

    @Override 
    protected Boolean doInBackground(final Void... params) { 
     try { 
      // Prepare callables. 
      final IsMaxRatingCallable call1 = new IsMaxRatingCallable(placeID); 
      final DidVoteCallable call2 = new DidVoteCallable(placeID, userID);   
      final List<Callable<Boolean>> callables = new ArrayList<Callable<Boolean>>();   
      callables.add(call1); 
      callables.add(call2); 

      // Execute them. 
      final ExecutorService service = Executors.newFixedThreadPool(2);    
      final List<Future<Boolean>> futures = service.invokeAll(callables, 5, TimeUnit.SECONDS); 

      // Check the result. 
      boolean result = true; 
      for(final Future<Boolean> future : futures) { 
       if(future.get()) { 
        result = false; 
       } 
      } 

      return result; 
     } catch (final InterruptedException e) { 
      e.printStackTrace(); 
     } catch (final ExecutionException e) { 
      e.printStackTrace(); 
     } 
     return false; 
    } 
} 

private class IsMaxRatingCallable implements Callable<Boolean> { 
    private final int placeID; 

    public IsMaxRatingCallable(final int placeID) { 
     this.placeID = placeID; 
    } 

    @Override 
    public Boolean call() throws Exception { 
     return Places.isMaxRating(placeID);   
    } 
} 

private class DidVoteCallable implements Callable<Boolean> { 
    private final int placeID; 
    private final int userID; 

    public DidVoteCallable(final int placeID, final int userID) { 
     this.placeID = placeID; 
     this.userID = userID; 
    } 

    @Override 
    public Boolean call() throws Exception { 
     return Votes.didVote(placeID, userID);   
    } 
} 

エラー

E/AndroidRuntime(19014): FATAL EXCEPTION: AsyncTask #1 
E/AndroidRuntime(19014): java.lang.RuntimeException: An error occured while executing doInBackground() 
E/AndroidRuntime(19014): at android.os.AsyncTask$3.done(AsyncTask.java:200) 
E/AndroidRuntime(19014): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
E/AndroidRuntime(19014): at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
E/AndroidRuntime(19014): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
E/AndroidRuntime(19014): at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
E/AndroidRuntime(19014): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
E/AndroidRuntime(19014): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
E/AndroidRuntime(19014): at java.lang.Thread.run(Thread.java:1027) 
E/AndroidRuntime(19014): Caused by: java.util.concurrent.CancellationException 
E/AndroidRuntime(19014): at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222) 
E/AndroidRuntime(19014): at java.util.concurrent.FutureTask.get(FutureTask.java:83) 
E/AndroidRuntime(19014): at com.vfa.android.planet.task.ShouldVoteTask.doInBackground(ShouldVoteTask.java:43) 
E/AndroidRuntime(19014): at com.vfa.android.planet.task.ShouldVoteTask.doInBackground(ShouldVoteTask.java:1) 
E/AndroidRuntime(19014): at android.os.AsyncTask$2.call(AsyncTask.java:185) 
E/AndroidRuntime(19014): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
E/AndroidRuntime(19014): ... 4 more 
+0

行は43行で、どの取消を処理するためにあなたの呼び出し可能でInterruptedException?そしてライン1には何がありますか?あなたのスタックトレースが1行目を表示するのは本当に奇妙です。 –

+0

43 >>> if(future.get()){何が問題なのですか? – Emerald214

+0

あなたの呼び出し可能なものの1つが例外を投げたと思います。それらのコードを投稿できますか? –

答えて

20

あなたは5秒のタイムアウトを使用して呼び出し可能オブジェクトを実行するために、あなたのエグゼキュータのサービスを依頼します。 the javadocによると:

[タイムアウトの終わりで]完了していないタスクが

をキャンセルしている私の推測では、タイムアウトに達したとexecutorがfuture.cancel()を呼び出すためfuture.get()CancellationExceptionを投げることです。

次のいずれかの可能性:

  • 増加タイムアウト
  • キャッチ優雅
+0

しかし、 'CancellationException'は' InterruptedException'を拡張していません。 –

+0

ところで、私は 'InvokeAll'の周りに' InterruptedException'を処理していますが、まだ 'CancellationException'を取得しています –

+0

@LuísSoaresいいえ、それはありません。 – assylias

関連する問題