Подтвердить что ты не робот

Подождите, пока значение boolean не изменится.

У меня есть поток, который ждет логического значения для изменения следующим образом:

while(!value)
{
  Thread.sleep(1000)
}
// Do some work after change of the value

Это не мой предпочтительный способ сделать это, вызвав массовое потребление процессора.

Есть ли способ заблокировать Thread, пока значение boolean не изменится?

4b9b3361

Ответ 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 
    }

};