Является ли wait (1) неблокирующим while (true) -loop более эффективным, чем использование wait() и notify()?

Использует ли цикл while(true) Java вместе с wait(1) больше или меньше ресурсов, чем цикл блокировки с wait() и notify()?

И имеют ли ядра процессора некоторые специальные (аппаратные) реализации, позволяющие wait(1)? Если да, существуют ли какие-либо ограничения при работе с такими неблокирующими циклами?

Пример:

while(true){
    wait(1);
    //do the job here...
}

(Только примечание: без wait(1) ядро ​​будет радикальным 100% в цикле while(true)...)

Ответ 1

Что касается первоначального вопроса о том, почему while (true); занимает больше CPU, чем while (true) { wait(1); }, рассмотрим: современный процессор может выполнять миллиарды команд в секунду. В цикле wait(1), считая, что он идеален и каждый раз один раз в миллисекундах, вы ограничиваете процессор до тысячей инструкций в секунду. Без него нет предела, и он может запускать узкую петлю миллиарды раз в секунду.

Что касается нового вопроса, который более эффективен, подход while (true) { wait(1); } против wait() и notify() ed...

Хорошо, скажем, вы ждете состояния. Вариант 1:

while (true) {
    wait(1);
    if (condition()) {
        break;
    }
}

против.

wait();

и в другом месте:

//code which causes condition() to be true
notify();

Предположим, что для выполнения условия требуется 10 секунд. В первом подходе вы вызываете wait(1) 10000 раз и проверяете condition() 10 000 раз. Во втором подходе вы вызываете wait() один раз и notify() один раз.

Ответ 2

Это трюк?

Когда вы помещаете "wait()" в цикл, он освобождает переменную синхронизации, позволяя другому потоку идти вперед и в конце концов уведомлять об этом потоке, чтобы продолжить. Поток не будет продолжаться и не будет использовать циклы процессора, пока он не получит уведомление. И почему wait/notify нужно вызывать из блоков или методов sync'd (неясно, если вы делаете это здесь).

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

Я рекомендую хорошую книгу о потоках Java и синхронизации, например http://www.amazon.com/Multithreaded-Programming-Java-Technology-Lewis/дп/0130170070

Ответ 3

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

Это станет особенно важным, если у вас есть много этих потоков, запущенных в качестве накладных расходов на поток.

Ответ 4

В принципе, Claudiu прав: CPU очень быстрые.

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

При программировании всегда есть два фактора:

1. количество кеша/ОЗУ и

2. время, необходимое для потока/процесса.

Поэтому все это о количестве ресурсов, используемых PER TIME: MB/s (или вообще: байты/с). Вы можете не только принимать правильные решения на основе выделенных ресурсов, сколько намерено делать многие программисты. Возможно даже, что выше неблокирующего floop использует намного меньше ресурсов, чем блокирующий, поскольку накладные расходы отсутствуют. Поэтому никогда не забывайте о временном измерении.

Заключение: более быстрые, неблокирующие программы (могут) использовать меньше ресурсов.