в чем разница между while (true) и wait () или thread join () - PullRequest
2 голосов
/ 21 мая 2019

Я хочу сохранить основной поток живым.Я нашел 3 варианта, и мне интересно, какой из них лучший.в чем различия и почему ??

есть ли среди них какой-то бесполезный ресурс?

  1. while (true) {}

  2. thread.join ()

  3. CountDownLatch (1) .await ()

Я попробовал их, и они работали хорошо.

while(true){}

thread.join()

CountDownLatch(1).await()

Ответы [ 3 ]

4 голосов
/ 21 мая 2019

Здесь:

while(true){}

делает "горячее" ожидание.Это означает: ваш процессор вращается на 100%, ничего не делая.Может быть, может быть, если вам действительно повезет, JVM обнаружит это и сможет не записывать циклы ЦП таким образом.

Принимая во внимание, что для join () мы находим:

Когда мы вызываем метод join () в потоке, вызывающий поток переходит в состояние ожидания.Он остается в состоянии ожидания, пока указанный поток не завершит свою работу.

(из этого учебника )

Итак, join () звучит как более здоровый подход.await() должно работать аналогичным образом.

Недостаток этих двух методов: они реагируют на прерывания потоков, поэтому, возможно, было бы неплохо поместить их в цикл "while true".

3 голосов
/ 21 мая 2019

есть ли среди них какой-то бесполезный ресурс?

Бесконечный цикл определенно расходует ресурсы, поскольку он повторяется без причины, и потребляет время и энергию вычислений.

другие два не должны тратить ресурсы, поскольку они позволяют ОС выполнять другие потоки в то время, пока они заблокированы.

2 голосов
/ 21 мая 2019

Ни один из них не является адекватным.

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();

Но это все же позволяет получателю запутать состояние (пытаясь получить его и испортить расписание), поэтому семафор должен быть спрятан за интерфейсом, позволяющим только другим выпустить его.

...