До Java 5.0 были только синхронизированные (встроенные блокировки) и изменчивые. После Java 5.0 была введена блокировка дисплея ReentrantLock.
Обзор ReentrantLock
ReentrantLock — это повторная блокировка. Она отличается от встроенной блокировки. Она требует явной блокировки и разблокировки при каждом использовании и предоставляет более продвинутые функции: справедливую блокировку, блокировку по времени, условную блокировку и блокировку с возможностью опроса. Блокировка позволяет эффективно избежать проблемы с работоспособностью, связанной с механизмом взаимоблокировки ReentrantLock.
Интерфейс блокировки:
Скопируйте код кода следующим образом:
публичный интерфейс Блокировка {
//Блокируем до тех пор, пока блокировка не будет получена или прервана
недействительная блокировка();
//Блокируем до тех пор, пока не будет получена блокировка или не будет выдано исключение при прерывании
void lockInterruptible() выдает InterruptedException;
//Получаем только тогда, когда доступна блокировка, в противном случае возвращаем напрямую
логическое значение tryLock();
//Получаем блокировку, только если она доступна в течение указанного времени, в противном случае возвращаемся напрямую и выдаем исключение при прерывании
логическое значение tryLock(долгое время, единица измерения TimeUnit) выдает InterruptedException;
недействительная разблокировка();
//Возвращаем условие, привязанное к этой блокировке
Условие новоеУсловие();
}
Блокировка использования
Скопируйте код кода следующим образом:
Блокировка блокировки = новый ReentrantLock();
блокировка.блокировка();
пытаться{
//обновляем статус объекта
}окончательно{
//Обратите внимание: для разблокировки должен быть блок кодаfinally
//В противном случае легко вызвать взаимоблокировку и другие проблемы с активностью.
блокировка.разблокировка();
}
Возможности ReentrantLock
Блокировки опроса и блокировки по времени
Запросы на опрашиваемую и временную блокировку реализуются с помощью метода tryLock(), который отличается от безусловного получения блокировок. ReentrantLock может иметь гибкий отказоустойчивый механизм. Многие случаи взаимоблокировки вызваны последовательными блокировками, и различные потоки пытаются получить доступ. locks. Он блокируется при блокировке и не освобождает уже удерживаемую блокировку, что в конечном итоге приводит к взаимоблокировке. Когда метод tryLock() пытается получить блокировку, если блокировка уже удерживается другим потоком, он немедленно возвращается в соответствии с методом установки вместо блокировки и ожидания. В то же время он освобождает блокировку, которую он удерживает после этого. возврат Вы можете вернуть его в соответствии с возвращенным. В результате выполняется повторная попытка или отмена, чтобы избежать взаимоблокировки.
справедливость
Конструктор ReentrantLock предоставляет два варианта: справедливую блокировку и нечестную блокировку (по умолчанию). Так называемые справедливые блокировки: потоки будут получать блокировки в том порядке, в котором они выдают запросы, а переход через очередь не разрешен, но для нечестных блокировок разрешен переход через очередь: когда поток запрашивает блокировку, если блокировка доступна; , то этот поток пропустит ожидающий поток в очереди и получит блокировку. Обычно мы хотим, чтобы все блокировки были несправедливыми. Потому что при выполнении операций блокировки справедливость значительно снижает производительность из-за накладных расходов на приостановку и восстановление потоков. Рассмотрим ситуацию: поток A удерживает блокировку, поток B запрашивает блокировку, поэтому поток B приостанавливается; когда поток A снимает блокировку, поток B пробуждается и в то же время пытается снова получить блокировку; C также запрашивает получение этой блокировки, тогда поток C, скорее всего, получит, использует и освободит эту блокировку до того, как поток B полностью пробудится. Это беспроигрышная ситуация. Момент, когда B получает блокировку (B может получить блокировку только после того, как проснется), не откладывается на более ранний срок, и пропускная способность также увеличивается. В большинстве случаев производительность нечестных блокировок выше, чем производительность справедливых блокировок.
Операции получения блокировки могут быть прерваны
Метод lockInterruptily получает блокировку, оставаясь при этом отзывчивым на прерывания, поэтому нет необходимости создавать другие типы операций бесперебойной блокировки.
ЧтениеWriteLockReadWriteLock
ReentrantLock — это стандартная блокировка мьютекса. Только один поток может удерживать блокировку одновременно. Блокировка чтения и записи отличается. Она предоставляет два объекта Lock, один из которых используется для операций чтения, а другой — для операций записи.
Скопируйте код кода следующим образом:
общедоступный интерфейс ReadWriteLock {
/**
* Возвращает блокировку, использованную для чтения.
*
* @return блокировку, используемую для чтения.
*/
Блокировка readLock();
/**
* Возвращает блокировку, используемую для записи.
*
* @return блокировку, используемую для записи.
*/
Блокировка writeLock();
}
Необязательная реализация:
1. Приоритет выпуска
2. Чтение переходов в строке
3. Реентерабельность
4.Понижение версии
5.Обновление
ReentrantReadWriteLock реализует интерфейс ReadWriteLock, а конструктор предоставляет два метода создания: справедливую блокировку и несправедливую блокировку. Блокировки чтения и записи подходят для ситуаций, когда происходит больше чтения и меньше записи, и могут обеспечить лучший параллелизм.
Пример кода копирования выглядит следующим образом:
общественный класс ReadWriteMap<K, V> {
частная карта Map<K, V>;
частная окончательная блокировка ReadWriteLock = новый ReentrantReadWriteLock();
частная окончательная блокировка readLock = lock.readLock();
частная окончательная блокировка writeLock = lock.writeLock();
public ReadWriteMap(Map<K, V> карта) {
this.map = карта;
}
общедоступный V get (ключ K) {
читатьLock.lock();
пытаться {
вернуть map.get(ключ);
} окончательно {
readLock.unlock();
}
}
public void put (ключ K, значение V) {
записьLock.lock();
пытаться {
map.put(ключ, значение);
} окончательно {
writeLock.unlock();
}
}
}