Future.get()没有返回所有结果

Kum*_*ish 0 java multithreading future executorservice

我正在创建15个可调用任务,并提交它们:

List<Future<MyResult>> futures = new ArrayList<Future<MyResult>>();
List<MyResult> myResults = new ArrayList<MyResult>();

for(int i = 1; i <= 15; i++){
    Callable<MyResult> task = new MyProcessor(//parameters);
    Future<MyResult> future = executorService.submit(task);
    futures.add(future);//used to iterate over to call get() to collect results in next for loop
}
Run Code Online (Sandbox Code Playgroud)

然后我收集了15个MyResult对象:

for(Future<MyResult> future : futures){
  try {
    MyResult myResult = future.get();
    processorResults.add(myResult);
    } catch (InterruptedException e) {
      //...
    } catch (ExecutionException e) {
      //...
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是:不是从get()方法返回所有15个MyResult对象,我有时会得到少于15个对象.有时12有时10有时甚至更小,有时甚至15.

我的印象是,get()方法是一个阻塞调用,并且将等待所有15个线程返回相应的结果,但看起来我错过了其中一些并继续前进.我做错了什么?我没有收集结果/正确等待结果?当从任何MyProcessor任务抛出ERROR时会发生这种情况吗?

Gra*_*ray 6

这可能意味着你的一些工作抛出了异常.很难从代码中分辨出来,但ExecutionException除了捕获和忽略它之外,你还需要做一些事情.

Future.get()抛出ExecutionExceptionCallable您提交抛出一个RuntimeExceptioncall()方法.MyResult如果方法正常返回,它将只返回你的return.您可以通过执行以下操作获取引发的异常:

} catch (ExecutionException e) {
    // account for the throw here, the original exception is in e.getCause()
    // log it, count it, or ...
    logger.error("Job threw exception: " + e.getCause());
}
Run Code Online (Sandbox Code Playgroud)

我的印象是get()方法是一个阻塞调用,并将等待所有15个线程返回相应的结果,

这是对的.当你调用future.get()它时会阻塞,直到作业结束 - 通过抛出异常或返回.如果正在进行的线程get()被中断,那么get()抛出一个InterruptedException也应该被捕获而不仅仅被忽略的线程.