Подождите, пока значение boolean не изменится.
У меня есть поток, который ждет логического значения для изменения следующим образом:
while(!value)
{
Thread.sleep(1000)
}
// Do some work after change of the value
Это не мой предпочтительный способ сделать это, вызвав массовое потребление процессора.
Есть ли способ заблокировать Thread, пока значение boolean не изменится?
Ответы
Ответ 1
Это не мой предпочтительный способ сделать это, вызвав массовое потребление процессора.
Если это действительно ваш рабочий код, просто сохраните его так. Проверка логического значения один раз в секунду вызывает отсутствие измеримой нагрузки ЦП. Ничего.
Реальная проблема заключается в том, что поток, который проверяет значение, может не видеть изменений, которые произошли в течение сколь угодно долгого времени из-за кэширования. Чтобы гарантировать, что значение всегда синхронизируется между потоками, вам нужно поместить ключевое слово volatile в определение переменной, то есть
private volatile boolean value;
Обратите внимание, что включение доступа в блок synchronized
, например, при использовании решения на основе уведомлений, описанного в других ответах, будет иметь тот же эффект.
Ответ 2
Вам нужен механизм, который позволяет избежать оживленного ожидания. Старый механизм wait/notify
чреват ловушками, поэтому предпочитайте что-то из библиотеки java.util.concurrent
, например CountDownLatch
:
public final CountDownLatch latch = new CountDownLatch(1);
public void run () {
latch.await();
...
}
И с другой стороны вызовите
yourRunnableObj.latch.countDown();
Однако, начиная нить, чтобы ничего не делать, но ждать, пока она понадобится, по-прежнему не лучший способ. Вы также можете использовать ExecutorService
, к которому вы отправляете в качестве задачи работу, которая должна выполняться при выполнении условия.
Ответ 3
Как насчет wait-notify
private Boolean bool = true;
private final Object lock = new Object();
private Boolean getChange(){
synchronized(lock){
while (bool) {
bool.wait();
}
}
return bool;
}
public void setChange(){
synchronized(lock){
bool = false;
bool.notify();
}
}
Ответ 4
Хорошо, возможно, этот должен решить вашу проблему. Обратите внимание, что каждый раз, когда вы делаете изменения, вы вызываете метод change(), который освобождает ожидание.
Integer any = new Integer(0);
public synchronized boolean waitTillChange() {
any.wait();
return true;
}
public synchronized void change() {
any.notify();
}
Ответ 5
Я предпочитаю использовать механизм mutex в таких случаях, но если вы действительно хотите использовать boolean, тогда вы должны объявить его изменчивым (чтобы обеспечить видимость изменений по потокам) и просто запустить цикл без учета тела с таким логическим значением, как условие:
//.....some class
volatile boolean someBoolean;
Thread someThread = new Thread() {
@Override
public void run() {
//some actions
while (!someBoolean); //wait for condition
//some actions
}
};