У меня есть основной цикл в моем потоке, и часть его проверяет, является ли idle boolean истинным. Если это так, он будет вызывать Thread.sleep(1)
на каждой итерации цикла. Это эффективный способ сделать это? Моя цель состоит в том, чтобы поток принимал минимальное использование ЦП в режиме ожидания.
В Java эффективно использовать 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
Более конкретно вы можете использовать условия ожидания - те, которые требуют тайм-аутов. Таким образом, вы можете, например, регистрировать сообщение так часто - сообщение, которое поможет вам отлаживать бесконечные ожидания. Вы также можете выполнить некоторую логику отката, если ожидания ожидания...