В Java эффективно использовать Thread.sleep(1) для простаивающего потока?

У меня есть основной цикл в моем потоке, и часть его проверяет, является ли idle boolean истинным. Если это так, он будет вызывать Thread.sleep(1) на каждой итерации цикла. Это эффективный способ сделать это? Моя цель состоит в том, чтобы поток принимал минимальное использование ЦП в режиме ожидания.

Ответ 1

Нет. Используйте Object.wait и убедитесь, что вы синхронизируете объект, содержащий логическое значение. Если вы не синхронизируете, а boolean не volatile, у вас нет барьера памяти, поэтому нет гарантии, что поток опроса увидит изменение в boolean.

В соответствии с javadoc:

Этот метод заставляет текущий поток (называть его T) размещать себя в наборе ожидания для этого объекта, а затем отказываться от любых и всех требований к синхронизации для этого объекта. Thread T отключается для целей планирования потоков и находится в состоянии покоя, пока не произойдет одна из четырех вещей:

  • Другой поток вызывает метод notify для этого объекта, а поток T выбирается произвольно как поток, который нужно разбудить.
  • Некоторый другой поток вызывает метод notifyAll для этого объекта.
  • Некоторые другие потоки прерывают поток T.
  • ...

чтобы поток не принимал процессор, пока он ждет уведомления.

Ниже приведен простой простой флаг с методом waitUntilIdle, который может вызывать метод main, и метод setIdle, который может быть вызван другим потоком.

public class IdleFlag {
  private boolean idle;

  public void waitUntilIdle() throws InterruptedException {
    synchronized (this) {
      while (true) {
        // If the flag is set, we're done.
        if (this.idle) { break; }
        // Go to sleep until another thread notifies us.
        this.wait();
      }
    }
  }

  public void setIdle() {
    synchronized (this) {
      this.idle = true;
      // Causes all waiters to wake up.
      this.notifyAll();
    }
  }
}

Ответ 2

Я согласен с @Mike Samuel, но я бы рекомендовал вам использовать параллельные блокировки пакетов...

Продолжайте с парадигмой Майка, просто замените его блокировку тем, что было введено в Java 5

Более конкретно вы можете использовать условия ожидания - те, которые требуют тайм-аутов. Таким образом, вы можете, например, регистрировать сообщение так часто - сообщение, которое поможет вам отлаживать бесконечные ожидания. Вы также можете выполнить некоторую логику отката, если ожидания ожидания...