0

我试图在使用 Future 执行另一个任务之前等待我的所有线程完成,但是出了点问题,因为我的未来只是在等待我的 for 循环的最后一个线程。

我的执行者方法:

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 循环中提交执行程序的地方出了点问题,但我该如何解决呢?

4

3 回答 3

3

您需要捕获每个返回的 Future,然后等待每个完成(使用 get on each)

或者,您可以执行以下操作:

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);

仅当其中的所有任务完成后才会返回。

于 2013-02-15T17:27:04.603 回答
1

你只是在等待最后一个Future完成。

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

这只会等待提交给 executor-service 的最后一个作业完成——其他作业仍然可以运行。您应该改为ExecutorServicedownloadImages(). 然后在您的等待方法中,您可以:

// 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().

于 2013-02-15T17:25:04.207 回答
1

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

于 2013-02-15T17:27:34.797 回答