2013-02-15 212 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當所有提交的任務完成時返回。

相關問題