这是继续通过earlier post,作为我的任务的一部分,我试图从URL下载文件使用可调用,并且每当发生异常我试图重新提交相同的可调用再次最大次数。终止和提交可执行文件到执行器
问题是,用目前的方法,我的程序并没有在一个快乐的一天的场景中完成所有的可调参数后终止,它会一直运行(可能是因为我使用的是非守护线程?不是吗?在给定的时间之后终止?)。
此外,我相信目前的设计将会阻止再次提交失败的可调用对象,因为我打电话给executor.shutdown()
,因此无论何时可调用失败,执行程序都将阻止向执行队列添加新的可调用对象。
任何想法如何克服?
public class DownloadManager {
int allocatedMemory;
private final int MAX_FAILURES = 5;
private ExecutorService executor;
private CompletionService<Status> completionService;
private HashMap<String, Integer> failuresPerDownload;
private HashMap<Future<Status>, DownloadWorker> URLDownloadFuturevsDownloadWorker;
public DownloadManager() {
allocatedMemory = 0;
executor = Executors.newWorkStealingPool();
completionService = new ExecutorCompletionService<Status>(executor);
URLDownloadFuturevsDownloadWorker = new HashMap<Future<Status>, DownloadWorker>();
failuresPerDownload = new HashMap<String, Integer>();
}
public ArrayList<Status> downloadURLs(String[] urls, int memorySize) throws Exception {
validateURLs(urls);
for (String url : urls) {
failuresPerDownload.put(url, 0);
}
ArrayList<Status> allDownloadsStatus = new ArrayList<Status>();
allocatedMemory = memorySize/urls.length;
for (String url : urls) {
DownloadWorker URLDownloader = new DownloadWorker(url, allocatedMemory);
Future<Status> downloadStatusFuture = completionService.submit(URLDownloader);
URLDownloadFuturevsDownloadWorker.put(downloadStatusFuture, URLDownloader);
}
executor.shutdown();
Future<Status> downloadQueueHead = null;
while (!executor.isTerminated()) {
downloadQueueHead = completionService.take();
try {
Status downloadStatus = downloadQueueHead.get();
if (downloadStatus.downloadSucceeded()) {
allDownloadsStatus.add(downloadStatus);
System.out.println(downloadStatus);
} else {
handleDownloadFailure(allDownloadsStatus, downloadStatus.getUrl());
}
} catch (Exception e) {
String URL = URLDownloadFuturevsDownloadWorker.get(downloadQueueHead).getAssignedURL();
handleDownloadFailure(allDownloadsStatus, URL);
}
}
return allDownloadsStatus;
}
private void handleDownloadFailure(ArrayList<Status> allDownloadsStatus, String URL) {
int failuresPerURL = failuresPerDownload.get(URL);
failuresPerURL++;
if (failuresPerURL < MAX_FAILURES) {
failuresPerDownload.put(URL, failuresPerURL);
// resubmit the same job
DownloadWorker downloadJob = URLDownloadFuturevsDownloadWorker.get(URL);
completionService.submit(downloadJob);
} else {
Status failedDownloadStatus = new Status(URL, false);
allDownloadsStatus.add(failedDownloadStatus);
System.out.println(failedDownloadStatus);
}
}
}
更新:之后我已经改变了while循环的条件,而非计数器!executor.isTerminated()
它的工作。 为什么执行者不会终止?
我调用shutdown()提交可调用之后但它并没有终止 –