Что произойдет, если Thread.yield()
вызывается в синхронизированной функции?
Как javadoc для Thread.yield()
состояний:
"[Это] подсказка планировщику о том, что текущий поток готов отдать свое текущее использование процессора. Планировщик может игнорировать эту подсказку."
Так что естьдве возможности:
- Ничего не происходит;т. е. вызов
yield()
немедленно возвращается. - Запланирован другой поток, и он начинает выполняться.В конце концов, этот поток перенесен, и вызов
yield()
возвращается.
Одна вещь не происходит .Поток не не освобождает мьютекс.Любой другой поток, который оказался заблокированным в ожидании получения мьютекса, будет оставаться заблокированным.
Разве это не синхронизированный метод, который не может быть вызван, пока не будет запущензадача заканчивает свою работу над этим?
Thread.yield
не является синхронизированным методом.(И даже если бы это было так, это заблокировало бы объект Thread
, а не блокировку, которую сейчас удерживает блок synchronized
.)
Итак, в вашем примере, вызов next()
гарантированно увеличивает счетчик ровно на 2. Если какой-то другой поток вызывает метод next()
, второй вызов останется заблокированным до (по крайней мере) после возврата первого вызова.
Javadoc также говоритthis:
«Этот метод редко подходит для использования.»
Другой вопрос: станет ли он тупиком для планирования потоков
Нет.Поток, вызвавший yield()
, будет в конечном итоге перенесен.
(Deadlock - это очень специфическое явление (см. статья в Википедии ), которое может происходить только при получении блокировки. Когда поток возвращает, он не получает и не снимает блокировки, поэтому он не может вызватьтупик.)
Теперь, когда поток возвращается, может пройти много времени, прежде чем он снова будет запланирован, особенно если есть много других выполняемых потоков с тем же приоритетом или более высоким .,Конечным результатом является то, что другие потоки, ожидающие получения блокировки, могут долго удерживаться.Это может чрезмерно увеличить споры и заторы.Но в конце концов, вызов yield()
вернется, вызов next()
вернется, и другой поток сможет получить блокировку.
Короче: вызов yield()
при удержании блокировки ухудшает производительность, но это не приведет к тупику.
Как говорит Javadoc, звонить по номеру yield()
редко бывает уместно.