1

私には3つのタスクがあります:

  • 最初: htmlFile --------\ の両方を同じ実行プログラムで順番にダウンロードします。正常に動作しています。
  • 2 番目: htmlFile を解凍します ----------/

  • 3 番目: イメージのダウンロード ------> 別のエグゼキュータで、イメージを 5 つのファイルに分割してダウンロードする必要があります。そのためには、FixedThreadPool(5) を使用しています。

しかし、クリックしてダウンロードすると、htmlDownload の終了を待たずに画像のダウンロードが開始されます。どうすれば executorPool が別の executor singleThread を待つことができますか??

メインクラス:

ExecutorService e = Executors.newSingleThreadExecutor();

            //Download HTML and Unzip Threads
            typeDownloaded = "html";
            DownloadUtil.downloadHtml(e, this, dns, port, uuid, filePathHtmlDownload, cookies, typeDownloaded);
            UnzipUtil.unZipHtml(e, this, filePathHtmlDownload, outputFolder, typeDownloaded);
            typeDownloaded = "images";
            DownloadUtil.downloadImages(e, this, dns, port, numImg, uuid, cookies, typeDownloaded);

私の DownloadUtil クラス:

public class DownloadUtil {

    private static Logger log = Logger.getLogger(LoginLocalServiceImpl.class.getName());

    public static void downloadHtml(Executor e, MainViewController controller, String dns, int port,
            String offlineUUID, String filePath, Map<String, String> cookies, String type) throws IOException {

        String urlHtml = "http://" + dns + ":" + port + Constants.TARGET_SERVICE_DOWNLOADFILES + offlineUUID;

        System.out.println(urlHtml);

        e.execute(new DownloaderTask(controller, urlHtml, filePath, cookies, type));

    }

    public static void downloadImages(Executor e, MainViewController controller, String dns, int port, int numImg,
            String uuid, Map<String, String> cookies, String type) throws SystemException, IOException {

        String filePath;
        String urlImages;

        if (numImg == 1) {
            filePath = System.getProperty("user.home") + File.separator + "Documents" + File.separator + "TargetApp" + File.separator + "TempImageDownload.zip";
            urlImages = "http://" + dns + ":" + port + Constants.TARGET_SERVICE_DOWNLOADIMAGES + uuid;
            e.execute(new DownloaderTask(controller, urlImages, filePath, cookies, type));

        } else {

            ExecutorService exec = Executors.newFixedThreadPool(numImg);

            for (int i = 0; i < numImg; i++) {
                filePath = System.getProperty("user.home") + File.separator + "Documents" + File.separator + "TargetApp" + File.separator + "TempImage" + i + "Download.zip";
                urlImages = "http://" + dns + ":" + port + Constants.TARGET_SERVICE_DOWNLOADIMAGES + uuid + "/?pos=" + (i);
                exec.execute(new DownloaderTask(controller, urlImages, filePath, cookies, type));

            }

        }


    }
}
4

2 に答える 2

1

次のように、html のダウンロードが完了するまで、イメージのダウンロード タスクの送信を遅らせることができます。

    final ExecutorService htmlDownloadExecutor = Executors.newSingleThreadExecutor();
    final ExecutorService imageDownloadExecutor = Executors.newFixedThreadPool(5);
    ...
    //Download HTML and Unzip Threads
    typeDownloaded = "html";
    final DownloaderTask htmlTask = DownloadUtil.downloadHtml(mainViewController, dns, port, uuid, filePathHtmlDownload, cookies, typeDownloaded);
    typeDownloaded = "images";
    final List<DownloaderTask> imageTasks = DownloadUtil.downloadImages(mainViewController, dns, port, numImg, uuid, cookies, typeDownloaded);

    // submit the html download escape
    htmlDownloadExecutor.execute(new Runnable() {
        @Override
        public void run() {
            // first run the html task
            htmlTask.run();
            // now submit the image tasks to run
            for (DownloaderTask imageTask : imageTasks) {
                imageDownloadExecutor.execute(imageTask);
            }

        }
    });

ヘルパー関数は、タスク インスタンスを返すように変更されました。タスク インスタンスは、適切なときに適切なエグゼキュータ サービス インスタンスに送信されます。html ダウンロード タスクは、html をダウンロードするためにすぐに送信されます。ダウンロードが完了すると、画像をダウンロードするタスクが送信されます。このソリューションにはスレッド ブロック操作 (CountDownLatch.await()) が含まれていないため、スケーラビリティとパフォーマンスが向上するはずです。

于 2013-02-07T19:01:51.693 に答える
0

GoogleのGuavaにはListenableFuture、タスクの完了時に他のタスクを実行する機能があります。もう1つの方法は、を使用しCountDownLatchてイメージのダウンロードスレッドを待機させることですが、待機中はこれらのスレッドを占有します。

于 2013-01-31T18:39:52.737 に答える