Что происходит с потоком, который не может получить блокировку? - PullRequest
4 голосов
/ 18 октября 2010

Что происходит с потоком, который не может получить блокировку (без вращения)? Переходит в заблокированное состояние. Как это выполняется снова?

Lock lck = new ReentrantLock();
lck.lock()
try
{
}
finally
{
   lck.unlock();
}

Ответы [ 3 ]

4 голосов
/ 18 октября 2010

Планировщик (или базовая реализация Lock) отвечает за его запуск. Если действие блокировки было полностью преобразовано в вызов мьютекса в ядро, планировщик не будет перепланировать поток, пока мьютекс не станет доступным; тогда планировщик ОС повторно пробудит поток. Чтение страницы википедии по Переключение контекста и ссылок оттуда может дать более глубокое понимание задействованных подробных механизмов. Вы также можете взглянуть непосредственно на код ReentrantLock, хотя в конечном итоге ваш вопрос сводится к некоторой комбинации примитивов, включая AbstractedQueuedSynchronizer, различные атомарные операции и, возможно, LockSupport.park()* 1009. * и unpark(). Вы можете дополнить свой вопрос или задать новый, если вас особенно интересуют блокировка / переключение контекста на уровне ядра или, в частности, как различные примитивы Java (например, j.u.c.Lock или мониторы примитивных объектов) реализованы поверх ядра.

На практике, поскольку это дорого, это может быть оптимизировано с помощью JVM или реализации блокировки. Например, поток может немного вращаться, чтобы увидеть, освобождена ли блокировка перед блокировкой.

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

Есть несколько замечательных ресурсов для изучения управления параллелизмом в Java. Ведущий пантеона - Java-параллелизма на практике . Некоторое интересное обсуждение производительности синхронизации в HotSpot 6.0 в Java SE 6 Performance Whitepaper и некоторых связанных слайдах .

2 голосов
/ 18 октября 2010

Получение блокировки никогда не удается. Представьте, что еще не выполнено.

Конечно, в некоторых случаях никогда не будет успешным, но нет события перехода, когда поток уведомляется о сбое & hellip; это просто продолжает ждать.

0 голосов
/ 18 октября 2010

Нить, удерживающая замок, разблокирует замок, а затем (или "a") заблокированная нить просыпается. Если поток, удерживающий блокировку, никогда не снимает блокировку (возможно, из-за того, что заблокирован на другом ресурсе), вы получаете тупик. Не вращающаяся блокировка обычно использует примитивы wait () / notify () или что-то подобное, так что поток уведомляется, когда блокировка снова становится доступной.

...