Ожидание завершения потока в Java
Главный поток часто должен продолжить работу только
после того, как фоновая часть закончилась: например,
файл дописан на диск или ответ API получен. Для этого
у Thread есть метод join(): вызывающий
поток блокируется, пока целевой не завершится.
Без join метод main может успеть
завершить программу раньше, чем успеет напечатать
сообщение только что запущенный worker.
Запуск worker и ожидание в главном потоке:
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread worker = new Thread(() -> {
System.out.println("worker done");
}, "worker");
worker.start();
worker.join();
System.out.println("main after join");
}
}
Строка main after join всегда идёт после
worker done, потому что join выстроил
порядок. Метод join объявляет
InterruptedException: его обрабатывают или
пробрасывают из main.
Вариант с ограничением времени ожидания через
join(long millis):
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread slow = new Thread(() -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("slow finished");
});
slow.start();
slow.join(100);
System.out.println("main continues");
slow.join();
}
}
Первый join(100) может вернуть управление
раньше, чем slow закончит паузу. Второй join()
без аргументов дожидается конца окончательно.
Запустите поток, который выводит "step".
Вызовите join() и только затем выведите
"all done". Убедитесь, что all done
никогда не появляется раньше step.