2015-12-02 3 views
1

Это должно продолжаться свыше 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() он работал. Почему исполнитель не заканчивается?

ответ

0

Вам необходимо позвонить ExecutorService.shutdown() и awaitTermination(), чтобы прекратить нитки после завершения всей вашей работы.

В качестве альтернативы вы можете предоставить свой собственный ThreadFactory при построении ExecutorService и пометить все свои темы как демона, чтобы они не сохранили ваш процесс после выхода основного потока.

+0

Я зову выключение() сразу после подачи вызываемых объектов , но он не заканчивается –

0

В ExecutorCompletionService Javadoc, мы видим примеры

CompletionService<Result> ecs 
     = new ExecutorCompletionService<Result>(e); 
    List<Future<Result>> futures 
     = new ArrayList<Future<Result>>(n); 
try { 
... 
} finally { 
     for (Future<Result> f : futures) 
      f.cancel(true); 
    } 

поэтому постарайтесь назвать отменить (истину), со всем вашим будущим, когда вам нужно остановить ExecutorCompletionService

Смежные вопросы