Задать вопрос
  • По какой причине java.util.concurrent.ExecutorService.awaitTermination() может не дожидаться завершения всех запущенных задач?

    @ElenaKovalinskaya Автор вопроса
    mayton2019, смотри какая штука. У меня в общей сложности 90 задач должно выполниться. В ExecutorService задаю пул из 6 потоков. Сначала запускатеся 6 потоков сразу, потом когда один из этих шести завершается, вместо него запускается новый, и так далее, пока все задачи не будут выполнены. Каждому новому потоку я задаю имя.
    Я сформировала файл дампа с помощью jstack, в нем я по именам вижу 6 потоков, которые выполнялись последними. У них состояние WAITING (parking). Там еще 83 потока, имена которых я не узнаю, у которых состояние WAITING (parking), RUNNABLE или WAITING (on object monitor)
    Потоку, который запускает всю эту тучу потоков, я тоже дала имя. Но в файле дампа я его не вижу почему-то.

    Меня очень удивляет то, что executorService.shutdown() так и не был выполнен. Это очень странно, поскольку запуск выполнения джобов должен запускаться только после executorService.shutdown(). Он не останавливает сами потоки. Он останавливает прием новых заявок и запускает выполнение тех, что уже были отправлены в executorService. Так должно быть, по идее. Но в моем случае все как-то по-другому работает.
  • По какой причине java.util.concurrent.ExecutorService.awaitTermination() может не дожидаться завершения всех запущенных задач?

    @ElenaKovalinskaya Автор вопроса
    mayton2019, Спасибо тебе за ответ. Я заменила этот участок кода на метод:
    private void shutdownAndAwaitTermination(final ExecutorService executorService, final Duration waitForTermination) {
            logger.info("Завершаю прием задач в пул с помощью shutdown");
            executorService.shutdown();
            try {
                logger.info("Начинаю ожидать завершение всех задач (awaitTermination)");
                boolean terminated = executorService.awaitTermination(waitForTermination.toHours(), TimeUnit.HOURS);
                logger.info("Ожидание завершено, все задачи должны быть завершены, результат завершения : " + terminated);
                if (!terminated) {
                    logger.info("Все же все задачи не завершились. Пытаюсь принудительно их завершить с помощью shutdownNow");
                    executorService.shutdownNow();
                    logger.info("Ожидаю завершения задач после shutdownNow");
                    if (!executorService.awaitTermination(5, TimeUnit.MINUTES))
                        logger.info("Executor service did not terminate. " + Instant.now());
                }
            } catch (InterruptedException ex) {
                logger.info("Выброшено исключение InterruptedException, снова пробую shutdownNow");
                executorService.shutdownNow();
                logger.info("Прерываю текущий поток");
                Thread.currentThread().interrupt();
            }
    
            logger.info("Метод shutdownAndAwaitTermination завершен");
        }


    и, судя по логам, по какой-то непонятной причине даже executorService.shutdown(); не был выполнен. Ни одна строка логов из этого метода не была выведена.
  • По какой причине java.util.concurrent.ExecutorService.awaitTermination() может не дожидаться завершения всех запущенных задач?

    @ElenaKovalinskaya Автор вопроса
    mayton2019, пришлось сделать перерыв в решении этой проблемы, меня переключили на другую задачу :)
    Я протестировала, подставив Thead.sleep вместо addressObjectProcessor.handle. В итоге, поведение такое же
  • По какой причине java.util.concurrent.ExecutorService.awaitTermination() может не дожидаться завершения всех запущенных задач?

    @ElenaKovalinskaya Автор вопроса
    mayton2019, спасибо тебе за ответ!
    У тебя здесь - бизнес логика
    addressObjectProcessor.handle(rootItem);
    - да, все верно. На данный момент можно считать, что мне безразлично, отработали ли все задачи, отправленные в ExecutorService . В контексте задачи, которую выполняет мой сервис, я могу запустить эти задачи в режиме -запустил-и-забыл, поэтому мне использование Future/Callable показалось немножко избыточным.
    Или запустил и тут-же скомандовал shutdown
    - Метод shutdown сами потоки не завершает, он сигнализирует о том, что прием заявок на исполнение закрывается. Проблема заключается в том, что pool.awaitTermination должен ожидать завершения всех задач, чтобы потом после этого выполнить код, следующий после него. Но что-то происходит, и основной поток, который должен дождаться выполнение всех задач, вдруг прекращает свое действие. Я сейчас пытаюсь с помощью jstack понять, что с ним происходит. Но мне все же интересно, какие могут быть причины этому.