Это должно продолжаться свыше 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);
}
}
}
Update: После того, как я изменил состояние время цикла на счетчике вместо !executor.isTerminated()
он работал. Почему исполнитель не заканчивается?
Я зову выключение() сразу после подачи вызываемых объектов , но он не заканчивается –