2013-02-15 125 views
0

我试图在使用Future执行另一个任务之前等待我的所有线程完成,但是有些事情是错误的,因为我的未来只是为我的for循环的最后一个线程扫视。未来等待FixedThreadPool在所有线程完成之前返回

我的遗嘱执行人方法:

public static Future<?> downloadImages(Executor e, MainViewController controller, String filePath, String dns, int port, int numImg, 
      String offlineUuid, Map<String, String> cookies, String type, String outputFolder) throws SystemException, IOException, InterruptedException { 

     String urlImages; 
     String filePath2; 
     Future future = null; 

     if (numImg == 1) { 

     //Some Code 

     } else { 

      type = "multimages"; 
      ExecutorService es = Executors.newFixedThreadPool(numImg); 


      for (int i = 0; i < numImg; i++) { 
       filePath2 = ""; 
       filePath2 = filePath + File.separator + "TargetApp" + File.separator + "TempImage" + i + "Download.zip"; 
       urlImages = "http://" + dns + ":" + port + Constants.TARGET_SERVICE_DOWNLOADIMAGES_PATH + offlineUuid + "/?pos=" + (i); 

       future = es.submit(new DownloaderAndUnzipTask(controller, urlImages, filePath2, outputFolder, cookies, type)); 
      } 

      return future; 
     } 
     return null; 

    } 

我等待的方法:

Future future = fullDownloadSelected(tableViewFull.getSelectionModel().getSelectedIndex()); 
         if (future != null) { 
          try { 
           future.get(); 
           if (future.isDone()); 
           System.out.println("Processamento de Imagens Acabou"); 
          } catch (ExecutionException ex) { 
           Logger.getLogger(MainViewController.class.getName()).log(Level.SEVERE, null, ex); 
          } 
当第一种方法创建的最后一个线程完成

我味精显示,但它应该已经完成​​了,当所有线程池已完成。我认为在for循环中提交我的执行程序的地方出了问题,但我该如何解决它?

回答

3

你需要捕捉每一个未来返回,然后等待每一个来完成(使用得到每个)

可以,或者,做这样的事情:

ExecutorService es = Executors.newFixedThreadPool(numImg); 
List<Callable> tasks = ... 
for (int i = 0; i < numImg; i++) { 
    tasks.add(your tasks); 
} 
List<Future<Object>> futures = es.invokeAll(tasks); 

这将只返回一次所有的任务都完成了。

1

您只需等待最后的Future即可完成。

future = es.submit(...); 
    ... 
return future; 
... 
// in waiting method, wait for the last job to finish 
future.get(); 

这只会等待提交给执行器服务的最后一个作业完成 - 其他作业仍可以运行。您应该从downloadImages()返回ExecutorService。然后,在你的等待你的方法做:

// you must always shut the service down, no more jobs can be submitted 
es.shutdown(); 
// waits for the service to complete forever 
es.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS); 

它可能更合理,为您的调用方法创建ExecutorService并将其传递到downloadImages()

1

您将在每次迭代中重新分配未来。
您可以使用invokeAll当所有提交的任务完成时返回。