2012-07-17 22 views
8

我想等待两个任务完成然后返回它们的结果,但有时我得到这个错误。为什么? CancellationException从何而来?CancellationException当使用ExecutorService

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?第一行是什么?很奇怪你的堆栈跟踪显示第1行。 – 2012-07-17 07:38:59

+0

43 >>> if(future.get()){它有什么问题? – Emerald214 2012-07-17 07:41:36

+0

我猜你的一个可调可以抛出异常。你可以发布这些代码吗? – 2012-07-17 07:42:45

回答

20

你问你的遗嘱执行人的服务以5秒的超时执行您可调用。据the javadoc:未完成[由超时结束]

任务被取消

我的猜测是,future.get()抛出一个CancellationException因为超时已经达到和执行调用future.cancel()

你既可以:

  • 增加超时
  • 抓一个InterruptedException在调用处理消除优雅
+0

但'CancellationException'不会扩展'InterruptedException'吗? – 2017-12-04 20:40:58

+0

顺便说一句,我在'invokeAll'周围处理'InterruptedException'并仍然得到'CancellationException' – 2017-12-04 20:42:18

+0

@LuísSoares不,它不。 – assylias 2017-12-04 21:05:32