После запуска дочернего потока, как нам ждать в родительском потоке завершения дочернего потока?

Для ожидания завершения дочернего потока в родительском потоке можно использовать метод join() для объекта потока. Метод join() блокирует выполнение родительского потока до тех пор, пока дочерний поток не завершится.

Вот пример:

public class Main {
    public static void main(String[] args) {
        Thread childThread = new Thread(() -> {
            // Код дочернего потока
            for (int i = 0; i < 5; i++) {
                System.out.println("Child Thread: " + i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        childThread.start(); // Запуск дочернего потока

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

        System.out.println("Child Thread has finished. Exiting Parent Thread.");
    }
}

В этом примере создается дочерний поток childThread, который выполняет некоторую работу (циклически выводит сообщения каждую секунду). После запуска дочернего потока вызывается метод join(), который блокирует родительский поток до тех пор, пока дочерний поток не завершится. После завершения дочернего потока родительский поток продолжает выполнение и выводит сообщение о завершении.