There is such a piece of code:
BlockingQueue<String> queue = new ArrayBlockingQueue(links.size()); for (String link : links) { queue.add(link); } ExecutorService executorService = Executors.newCachedThreadPool(); int threadsNumber = Integer.valueOf(arguments.get("-n")); for (int i = 0; i < threadsNumber; i++) { executorService.submit(new Consumer(queue, arguments.get("-o"), Integer.valueOf(arguments.get("-l")))); } while (!queue.isEmpty()) { Thread.sleep(1000); } executorService.shutdownNow(); System.out.println("Все файлы были успешно скачены"); The last lines mean I'm going to close the thread pool when all the messages in the queue have been read. Everything is fine, but there is a problem at the moment when one of the threads takes the last message from the queue. The condition !queue.isEmpty() stops executing and the program terminates before this message is processed.
How can I make the program complete only after processing all messages in the queue?
Consumer run method
@Override public void run() { try { while (true) { if (!queue.isEmpty()) { String stringURL = queue.take(); String inputFileName = Paths.get(stringURL).getFileName().toString(); String outputFileName = new File(new File(storageFilesDirectory), inputFileName).toString(); Downloader.download(stringURL, outputFileName, speedLimit); System.out.println(String.format("Файл %s был успешно скачен", inputFileName)); } Thread.sleep(500); } } catch (InterruptedException e) { } catch (FileCouldNotBeDownloaded e) { System.out.println(String.format("Произошла ошибка скачивания файла.")); } } I have only two threads in the pool, and the messages in the queue can be unlimited.
executorService.awaitTerminationdo not consider? - Senior PomidorawaitTermination, and to limit the number of threads, usefixedThreadPool. - zRrr