0

Futureを使用して別のタスクを実行する前に、すべてのスレッドが終了するのを待とうとしていますが、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 に送信された最後のジョブが完了するのを待つだけです。他のジョブは引き続き実行できます。代わりにExecutorServiceから を返す必要がありdownloadImages()ます。次に、待機メソッドで次のことを行います。

// 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 に答える