Ни один из них не является адекватным.
while(true){}
Бесконечный цикл занятости постоянно вращается на процессоре, генерируя тепло и потребляя энергию. Его нельзя остановить чисто.
thread.join()
Ожидание завершения другого потока. Это отличается от других, потому что это может закончиться, вместо того, чтобы работать вечно Но если приложение состоит только из другого потока, работающего до его завершения, почему бы тогда не запустить код из основного потока вместо создания другого потока и ожидания его завершения?
CountDownLatch(1).await()
Создание монитора и ожидание его навсегда. Это почти так же, как:
Object o = new Object();
synchronized (o) {
o.wait();
}
Опять же, нет чистого способа остановить программу.
Последний, CountdownLatch, будет наиболее близок к подходу, с которым можно работать. Вместо того, чтобы сразу выбрасывать ссылку на защелку, передайте ее коду, управляющему выполнением, чтобы он мог сообщить основному потоку, что пора остановиться. Но сам CountdownLatch как сигнал для условия выхода сбивает с толку. Сигнал выхода является логическим, поэтому семафор будет более подходящим
Semaphore exitPermission = new Semaphore(0);
// Pass exit permission around.
exitPermission.acquire();
Но это все же позволяет получателю запутать состояние (пытаясь получить его и испортить расписание), поэтому семафор должен быть спрятан за интерфейсом, позволяющим только другим выпустить его.