В чем разница между эксклюзивной блокировкой и общей блокировкой?

119

Согласно Википедии,

Совместно используемые блокировки иногда называют «блокировками чтения», а эксклюзивные блокировки - «блокировками записи».

Можете ли вы объяснить причину терминов «совместно используемый» и «эксклюзивный»?

Роза Перроне
источник
Неисключительная блокировка - это другое название разделяемой блокировки?
Рамеш Папаганти

Ответы:

419

Я написал этот ответ, потому что подумал, что это будет забавная (и подходящая) аналогия:

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

Пока учитель пишет что-то (эксклюзивный замок) на доске:

  1. Никто не может его прочитать, потому что он все еще пишется, и она блокирует ваше представление => Если объект заблокирован исключительно, общие блокировки не могут быть получены .

  2. Другие учителя тоже не подойдут и не начнут писать, или доска станет нечитаемой и смущает учеников => Если объект заблокирован исключительно, другие эксклюзивные блокировки получить нельзя .

Когда ученики читают (общие замки), что написано на доске:

  1. Все они могут читать, что на нем, вместе => Могут сосуществовать несколько общих блокировок .

  2. Учитель ждет, пока они закончат чтение, прежде чем очистить доску, чтобы написать больше => Если одна или несколько общих блокировок уже существуют, эксклюзивные блокировки не могут быть получены .

ArjunShankar
источник
2
очень хорошее объяснение. Однако PO спросил о происхождении «общих» и «эксклюзивных» наименований, а не объяснение терминов как таковых.
serhio
Это «Если одна или несколько общих блокировок уже существуют, эксклюзивные блокировки не могут быть получены». правда? в контексте ReentrantReadWriteLock? Я думал, что блокировку записи можно получить в любой момент, иначе из-за непрерывного чтения может произойти голод.
Kanagavelu Sugumar
1
@KanagaveluSugumar, да, это правда. Вы просто не можете получить блокировку записи, если другой объект уже имеет блокировку чтения для того же объекта. В этом весь смысл блокировки чтения-записи. Если вам случится что-то перезаписать, пока кто-то это читает, что тогда они прочитают? Я не знаю, почему вы выбрали именно блокировку чтения-записи «повторного входа», но повторное вхождение означает, что владелец блокировки повторного входа может «заблокировать ()» ее снова и все последующие lock()вызовы после первый вернется немедленно и успешно. т.е. вы можете успешно заблокировать то, что у вас уже есть.
ArjunShankar
2
Вы также упоминаете, что «я думал, что блокировку записи можно получить в любое время, иначе может произойти голодание для записи из-за непрерывного чтения» - этого просто не может быть. Блокировка записи не может быть получена, пока какой-либо другой объект уже имеет блокировку чтения / записи. Что может случиться, так это то, что если несколько сущностей уже ожидают блокировки объекта, то ожиданию writerотдается предпочтение перед ожидающими считывателями, когда блокировка выбирает, кто получит блокировку следующей (когда она разблокирована его текущим владельцем). Это о политике .
ArjunShankar
Спасибо! Я выбрал ReentrantReadWriteLock; поскольку это класс реализации ReadWriteLock в java. Тогда поднимается ли какой-либо флаг или установлен более высокий приоритет, чтобы сказать, что новые потоки чтения будут ждать, когда поток записи начнется в ожидании? Потому что как избежать остановки потока записи из-за непрерывного запроса на чтение?
Kanagavelu Sugumar
34

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

Таким образом, блокировка чтения говорит «вы можете читать сейчас, но если вы хотите писать, вам придется подождать», тогда как блокировка записи говорит «вам придется подождать».


Я понимаю, что вы проводите исследования в поддержку своих исследований, но я не могу удержаться от желания читать лекции.

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

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

Простое объединение всего состояния сеанса в структуру было огромным улучшением. Изменения в состоянии сеанса просто изменяли значения членов структуры состояния сеанса. Поскольку ни у одного другого сеанса не было случая или даже возможности напрямую ссылаться на состояние сеанса, единственной обновляемой коллекцией был список сеансов. В результате во время сеанса блокировка была совершенно ненужной , только в начале и в конце, а пропускная способность увеличилась в 3000 раз.

Другой распространенный сценарий блокировки - это ресурсы, совместно используемые потоками пользовательского приложения. Большинство современных фреймворков решают эту проблему с помощью сообщений, а не блокировок; когда вы «переходите к потоку пользовательского интерфейса», вы фактически ставите в очередь сообщение, содержащее указатель на функцию и некоторые параметры (или делегата и фрейм стека в зависимости от реализации).

Питер Вон
источник
6
  • Исключительная блокировка или блокировка записи дает процессу монопольный доступ для записи в указанную часть файла. Пока установлена ​​блокировка записи, никакой другой процесс не может заблокировать эту часть файла.

  • Совместная блокировка или блокировка чтения запрещает любому другому процессу запрашивать блокировку записи для указанной части файла. Однако другие процессы могут запрашивать блокировки чтения.

Подробнее об этом: http://www.gnu.org/software/libc/manual/html_node/File-Locks.html

TOC
источник
2

То же самое и со стороны базы данных. Согласно документации Oracle

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

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

user2155031
источник