Сравнивайте с английским: нажмите на абзац — оригинал откроется в окне. Кнопка EN под абзацем показывает его прямо в тексте.
Содержание
Введение
В информатике реинтеррантный мьютекс (рекурсивный мьютекс, рекурсивный замок) – это особый тип механизма взаимного исключения (мьютекс), который может быть заблокирован несколько раз одним и тем же процессом/потоком без возникновения взаимоблокировки. В то время как любая попытка заблокировать обычный мьютекс (замок) завершится неудачей или приведёт к блокировке, если мьютекс уже заблокирован, рекурсивный мьютекс позволит это сделать, если и только если блокирующий поток является тем, который уже владеет замком. Как правило, рекурсивный мьютекс отслеживает количество раз, когда он был заблокирован, и требует выполнения такого же количества операций разблокировки, прежде чем другие потоки смогут его заблокировать.
In computer science, the reentrant mutex (recursive mutex, recursive lock) is a particular type of mutual exclusion (mutex) device that may be locked multiple times by the same process/thread, without causing a deadlock. While any attempt to perform the "lock" operation on an ordinary mutex (lock) would either fail or block when the mutex is already locked, on a recursive mutex this operation will succeed if and only if the locking thread is the one that already holds the lock. Typically, a recursive mutex tracks the number of times it has been locked, and requires equally many unlock operations to be performed before other threads may lock it.
Практическое применение
В. Ричард Стивенс отмечает, что рекурсивные блокировки "непросто" использовать правильно, и рекомендует их применение для адаптации однопоточного кода без изменения API, но "только если нет другого возможного решения". Встроенный механизм синхронизации языка Java, монитор, использует рекурсивные блокировки. Синтаксически, блокировка – это блок кода, перед которым стоит ключевое слово "synchronized" и любая ссылка на объект в скобках, используемая в качестве мьютекса. Внутри синхронизированного блока данный объект может быть использован как переменная условия посредством вызова wait, notify или notifyAll для него. Таким образом, все объекты являются одновременно рекурсивными мьютексами и переменными условия.
W. Richard Stevens notes that recursive locks are "tricky" to use correctly, and recommends their use for adapting single threaded code without changing APIs, but "only when no other solution is possible". The Java language's native synchronization mechanism, monitor, uses recursive locks. Syntactically, a lock is a block of code with the 'synchronized' keyword preceding it and any Object reference in parentheses that will be used as the mutex. Inside the synchronized block, the given object can be used as a condition variable by doing a wait , notify , or notifyAll on it. Thus all Objects are both recursive mutexes and condition variables.
Приобретение
Получите управляющее условие. Если владелец установлен и это не текущий поток, дождитесь уведомления об управляющем условии (это также освобождает условие). Установите владельца в текущий поток. Идентификатор владельца должен быть уже очищен к этому моменту, если только вызывающий поток ещё не является владельцем. Увеличьте счётчик приобретений (должно всегда приводить к 1 для новых владельцев). Освободите управляющее условие.
Acquire the control condition. If the owner is set and not the current thread, wait for the control condition to be notified (this also releases the condition). Set the owner to the current thread. The owner identifier should have already been cleared at this point unless the acquirer is already the owner. Increment the acquisition count (should always result in 1 for new owners). Release the control condition.
Релиз
Получить управляющее состояние, удостоверившись, что владелец является освобождающим. Уменьшить счетчик приобретений, удостоверившись, что счетчик больше или равен нулю. Если счетчик приобретений равен нулю, очистить информацию о владельце и уведомить управляющее состояние. Освободить управляющее состояние.
Acquire the control condition, asserting that the owner is the releaser. Decrement the acquisition count, asserting that the count is greater than or equal to zero. If the acquisition count is zero, clear the owner information and notify the control condition. Release the control condition.