Повторный вход означает, что блокировки устанавливаются для каждого потока, а не для каждого вызова.
Это вводящее в заблуждение определение. Это правда (вроде как), но это упускает из виду реальную суть.
Реентерабельность означает (в общей терминологии CS/IT), что вы что-то делаете, и пока вы это делаете, вы делаете это снова. В случае с блокировками это означает, что вы делаете нечто подобное в одном потоке:
- Получите блокировку на "foo".
- Сделай что-нибудь
- Получите блокировку на "foo". Обратите внимание, что мы не сняли ранее полученную блокировку.
- ...
- Снять блокировку на "foo"
- ...
- Снять блокировку на "foo"
При повторном входе в блокировку/механизм блокировки попытка получить ту же блокировку будет успешной и увеличит внутренний счетчик, принадлежащий блокировке. Замок будет снят только тогда, когда текущий владелец замка освободит его дважды.
Вот пример в Java с использованием блокировок/мониторов примитивных объектов... которые являются реентерабельными:
Object lock = new Object();
...
synchronized (lock) {
...
doSomething(lock, ...)
...
}
public void doSomething(Object lock, ...) {
synchronized (lock) {
...
}
}
Альтернативой повторному вхождению является блокировка без повторного входа, при которой попытка потока получить блокировку, которую он уже удерживает, будет ошибкой.
Преимущество использования повторных блокировок заключается в том, что вам не нужно беспокоиться о возможности сбоя из-за случайного получения блокировки, которая у вас уже есть. Недостатком является то, что вы не можете предположить, что ничто из того, что вы вызываете, не изменит состояние переменных, для защиты которых предназначена блокировка. Однако обычно это не проблема. Блокировки обычно используются для защиты от одновременных изменений состояния, сделанных другими потоками.
Так что мне не нужно рассматривать взаимоблокировки?
Да, вы делаете.
Поток не будет блокироваться сам по себе (если блокировка является повторной). Однако вы можете получить взаимоблокировку, если есть другие потоки, которые могут заблокировать объект, который вы пытаетесь заблокировать.
person
Stephen C
schedule
12.05.2013