Как в Java один поток может дождаться завершения другого?

«Как в Java один поток может дождаться завершения другого?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Java для ожидания завершения работы другого потока используется метод join() класса Thread.

Принцип работы: Когда поток A вызывает threadB.join(), поток A переходит в состояние WAITING и будет заблокирован до тех пор, пока поток B не завершит свое выполнение.

Пример базового использования:

Thread workerThread = new Thread(() -> {
    System.out.println("Рабочий поток начал работу.");
    try {
        Thread.sleep(3000); // Имитация долгой задачи
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("Рабочий поток завершил работу.");
});

workerThread.start(); // Запускаем поток
System.out.println("Основной поток запустил workerThread.");

try {
    workerThread.join(); // Основной поток ждет завершения workerThread
} catch (InterruptedException e) {
    e.printStackTrace();
}

System.out.println("Основной поток продолжает выполнение после join().");

Важные особенности метода join():

  • Бросает исключение InterruptedException, если ожидающий поток будет прерван.
  • Поддерживает таймаут: join(long millis) или join(long millis, int nanos).
  • Немедленный возврат, если целевой поток уже завершен или не был запущен.
  • Для ожидания нескольких потоков необходимо последовательно вызвать join() для каждого из них.