Введение

В информатике реинтеррантный мьютекс (рекурсивный мьютекс, рекурсивный замок) – это особый тип механизма взаимного исключения (мьютекс), который может быть заблокирован несколько раз одним и тем же процессом/потоком без возникновения взаимоблокировки. В то время как любая попытка заблокировать обычный мьютекс (замок) завершится неудачей или приведёт к блокировке, если мьютекс уже заблокирован, рекурсивный мьютекс позволит это сделать, если и только если блокирующий поток является тем, который уже владеет замком. Как правило, рекурсивный мьютекс отслеживает количество раз, когда он был заблокирован, и требует выполнения такого же количества операций разблокировки, прежде чем другие потоки смогут его заблокировать.

Практическое применение

В. Ричард Стивенс отмечает, что рекурсивные блокировки "непросто" использовать правильно, и рекомендует их применение для адаптации однопоточного кода без изменения API, но "только если нет другого возможного решения". Встроенный механизм синхронизации языка Java, монитор, использует рекурсивные блокировки. Синтаксически, блокировка – это блок кода, перед которым стоит ключевое слово "synchronized" и любая ссылка на объект в скобках, используемая в качестве мьютекса. Внутри синхронизированного блока данный объект может быть использован как переменная условия посредством вызова wait, notify или notifyAll для него. Таким образом, все объекты являются одновременно рекурсивными мьютексами и переменными условия.

Приобретение

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

Релиз

Получить управляющее состояние, удостоверившись, что владелец является освобождающим. Уменьшить счетчик приобретений, удостоверившись, что счетчик больше или равен нулю. Если счетчик приобретений равен нулю, очистить информацию о владельце и уведомить управляющее состояние. Освободить управляющее состояние.