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

Thread.yield() считается вредным?

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

while( !foo.isInitialized() ) {
     Thread.yield();
}

в основной теме. Я знаю, что есть более надежные решения; Тем не менее, загрузчик не создан мной, а это в основном библиотека только для чтения (я не могу просто wait(), потому что я не могу заставить его отправить мне notify(), а также не умереть после завершения), и мне просто нужно подождать, пока загрузка не будет выполнена.

Java doc говорит, что (обратите внимание, что это было not present в 1.6 документах и ​​был добавлен 1.7 документами)

Редко использовать этот метод.

NetBeans предупреждает меня, что

Вызов метода yield() on java.lang.Thread обычно используется для маскировки проблем синхронизации и его следует избегать.

Google Codepro AnalytiX, OTOH, говорит

Метод Thread.yield() не должен использоваться, потому что его поведение несовместимо на всех платформах.

Должен ли я быть связан с этими предупреждениями и пытаться найти лучшее решение (все предложения приветствуются), или я должен рассматривать их как "предупреждающий шум" и подавлять/игнорировать их?

Примечание. Я думал о очевидной возможности использования sleep() (Являются ли ссылки на Thread.sleep(0) и Thread.yield() эквивалентными? Вот); все же, если yield ing не имеет "бонуса" от постоянного сна, почему Java предоставляет его вообще - и каковы фактические действительные варианты использования для него?

Немного связаны: Есть ли лучшее решение для Thread.yield()? и Thread.Sleep или Thread.Yield

4b9b3361

Ответ 1

Основная проблема с вызовом Thread.yield() в цикле while без механики ожидания заключается в том, что он легко становится циклом ожидания ожидания, используя 100% одного из ваших ядер.

Если нет никаких других потоков для планирования, когда вы уступаете, полученный поток, вероятно, будет перепланирован очень быстро и, следовательно, приведет к высокому использованию процессора.

Кроме этого, в этом случае я не вижу, чтобы это было более вредно. Тем не менее, это довольно бессмысленно - если вы собираетесь писать цикл busy-wait, вы можете просто сделать while (!foo.isInitialized()); и избегать подчеркивания планировщика.

Что вам следует делать, если вы не можете иметь механизм уведомления, - это, по крайней мере, спать в цикле. Это позволит вашим процессорам немного отдохнуть.

Типичная реализация такого цикла:

while(!foo.isInitialized()) { 
    try {
        Thread.sleep(20);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        return; // or handle some other way
    }
}