>我有 3 个任务要做:
- 首先:下载html文件--------\ 两者都在同一个执行器中按顺序工作正常。
-
第二:解压缩 html文件---------/
-
第三:下载图像------> 在另一个执行器中,我需要下载分成 5 个文件的图像,为此我使用的是 FixedThreadPool(5),换句话说,我需要 5 个平行下载。
但是当我点击下载时,我的图像下载开始而不等待html下载完成,我该如何让我的执行器池等待我的另一个执行器单线程?
主类:
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);
我的下载实用程序类:
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));
}
}
}
}
您可以延迟提交映像下载任务,直到 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()),因此它应该更具可扩展性/性能。
谷歌的Guava ListenableFuture
将在完成任务后执行其他任务。另一种方法是使用CountDownLatch
让图像下载线程等待,但这会在等待时占用这些线程。