Один из общих подводных камней при работе с многопоточностью в Java заключается в управлении временем выполнения потоков. Конкретно, разработчики часто сталкиваются с необходимостью ожидания завершения всех потоков перед продолжением выполнения основного потока.
Примером может служить следующий сценарий: имеется некоторое количество задач, которые должны выполняться параллельно и ограничены определенным количеством потоков. Например, 4 потока, которые обрабатывают задачи из общего пула.
ExecutorService taskExecutor = Executors.newFixedThreadPool(4); while(...) { taskExecutor.execute(new MyTask()); } //...здесь необходимо дождаться завершения всех потоков
Так как же дождаться завершения всех потоков? Существует несколько подходов, но одним из наиболее элегантных и простых решений является использование метода shutdown()
и awaitTermination()
класса ExecutorService
.
Во-первых, используется метод shutdown()
. Этот метод инициирует упорядоченное завершение работы, при котором ранее отправленные задачи выполняются, но новые задачи не принимаются.
taskExecutor.shutdown();
Затем используется метод awaitTermination()
, который блокирует дальнейшее выполнение текущего потока до тех пор, пока все задачи не будут выполнены после запроса на завершение работы, или пока не истечет время ожидания, или пока поток не будет прерван, в зависимости от того, что произойдет раньше.
try { taskExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); } catch (InterruptedException e) { // обработка исключения }
Таким образом, при использовании этих двух методов, можно гарантировать, что основной поток ожидает завершения всех задач, выполняемых в пуле потоков, перед тем как продолжить свое выполнение. Это позволяет избегать использования глобальных счетчиков задач или бесконечных циклов для мониторинга статуса задач.
Добавить комментарий