Что происходит с потоками при вызове get()?

 
 
 
Сообщения:2
Добрый день! Есть код, который обрабатывает файлы. Фрагмент кода:
ExecutorService pool = Executors.newFixedThreadPool(argument.getThreads());
        List<Future<?>> result = new ArrayList<>();
        for(int i = 0; i < argument.getThreads(); i++){
            result.add(pool.submit(new Downloader(argument.getTargetDirectory(), blockingQueue)));
        }
        for(Future<?> e : result){
            try{
                e.get();
            } catch (InterruptedException exc){
                System.out.println("");
            }
        }

Я создаю пул потоков и массив Future, в который "кладу потоки". После чего дожидаюсь результата выполнения потока (e.get()). Выполнив программу несколько раз, я заметил, что последние файлы обрабатывает только один поток. Этому есть объяснения? Правильно ли я понимаю, что метод get() НЕ блокирует другие потоки пула?
Изменен:10 янв 2019 12:14
 
 
Сообщения:791
VictorKomarov:
Я создаю пул потоков и массив Future, в который "кладу потоки"

Future - это не поток. Это средство связи с параллельным потоком, типа почтового ящика. Параллельный поток туда положит значение, а другой возьмет с помощью get(), ожидая значения если его там еще нет. Фактически это блокирующая очередь размером 1.
VictorKomarov:
я заметил, что последние файлы обрабатывает только один поток. Этому есть объяснения?
Ну это надо смотреть, как написан Downloader. Возможно, Downloader при ошибке ввода-вывода отваливается, и в конце остается только один рабочий экземпляр, который и тянет всю работу.
VictorKomarov:
Правильно ли я понимаю, что метод get() НЕ блокирует другие потоки пула?
другие - это какие? Как было сказано, Future - это не поток. Тот поток, который вызывает get(), может быть заблокирован, но он не является потоком пула, поэтому ответ - метод get() не блокирует вообще никакие потоки пула.
Изменен:10 янв 2019 13:45
 
 
Сообщения:2
rfq
 public void run(){
        while ( !queue.element().getLink().equals("end") ){ 
            myFile file = queue.poll();
            if (file == null) {
                return;
            }
            Path target = Paths.get(targetDirectory.toString(), file.getName());
            try (InputStream in = new URL(file.getLink()).openStream()) {
                Files.copy(in, target);
            } catch (MalformedURLException e) {
                System.out.println("Не получилось обратиться к " + file.getLink());
            } catch (IOException e) {
                System.out.println("Не получилось обработать " + file.getLink());
            }
        }
    }

Это метод run из Downloader. На счет Future понял. Нашел свою ошибку. Спасибо за ответ!
Изменен:11 янв 2019 06:07
 
Модераторы:Нет
Сейчас эту тему просматривают:Нет