Почему метод yield в java не снимает блокировку?

1

У меня есть некоторые сомнения относительно метода yield в java. Поскольку, когда мы используем его как Thread.yield(), поток переходит в состояние runnable и дает шанс запустить другой поток, но поток, который вызывает выход, не освобождает блокировку. Таким образом, будут выполняться только те потоки, кроме тех, кто ожидает освобождения блокировки. Итак, когда и в каком сценарии этот метод доход полезен.

  • 1
    Я бы предложил прочитать этот пост: stackoverflow.com/questions/6979796/…
  • 0
    «замок»: какой замок?
Показать ещё 3 комментария
Теги:
multithreading

2 ответа

4

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

Я не знаю каких-либо современных операционных систем, поддерживающих Java, но не поддерживающих превентивные потоки, поэтому в современных Java-программах он мало/не используется.

Thread.yield() имеет ничего общего с блокировками, не документирован, чтобы каким-либо образом повлиять на блокировки, и не должен использоваться в предположении, что он освободит блокировку.


Изменение: этот ответ SO содержит гораздо больше информации о том, как Thread.yield() (по крайней мере, как JDK 1.6).

  • 0
    Он также используется в предположении, что поток откажется от своего оставшегося временного интервала в вытесняющих ОС. Хотя, действительно ли это работает, другой вопрос - скорее черная магия, и JVM действительно только прилагает максимум усилий.
1

Я согласен с @kdgregory, Thread.yield(), вероятно, не должен использоваться в современных Java-программах. Но не потому, что разрешить одному потоку уступать другим - это плохая идея: просто потому, что если вам действительно нужно уступить(), то вы, вероятно, повторно изобретаете алгоритм, который уже реализован в java.util.concurrent.


Одно можно сказать наверняка: если вы собираетесь уступить(), не делайте этого внутри синхронизированного блока. Вся точка yield() должна позволить другим потокам работать. Вся суть синхронизированного блока: "Я хочу закончить этот бит, прежде чем любой другой поток начнет его".

Ваша цель всегда должна заключаться в том, чтобы ваша программа тратила как можно меньше времени на синхронизированные блоки. Чем больше времени он проводит в синхронизированных блоках, тем меньше он будет выигрывать от нескольких процессоров. Каждый синхронизированный блок является узким местом. Даже маленький может иметь большое значение. Читайте об Amdahl Law.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню