Ответ
ReadWriteLock — это интерфейс в пакете java.util.concurrent.locks, который реализует шаблон разделения блокировок для чтения и записи. Он позволяет нескольким потокам одновременно читать общий ресурс, но требует эксклюзивной блокировки для операций записи.
Основные принципы:
- Блокировка чтения (
ReadLock): Может быть получена несколькими потоками одновременно, но только при отсутствии активной блокировки записи. - Блокировка записи (
WriteLock): Эксклюзивна. Когда она удерживается, никакие другие блокировки (ни на чтение, ни на запись) не могут быть получены.
Типичное использование (на примере ReentrantReadWriteLock):
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class SharedResource {
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
private Object data;
public Object read() {
rwLock.readLock().lock();
try {
// Безопасное чтение данных несколькими потоками
return data;
} finally {
rwLock.readLock().unlock(); // Важно освобождать в finally
}
}
public void write(Object newData) {
rwLock.writeLock().lock();
try {
// Эксклюзивная запись. Другие читатели/писатели ждут.
this.data = newData;
} finally {
rwLock.writeLock().unlock();
}
}
}
Преимущества:
- Повышение производительности в сценариях с частым чтением и редкой записью.
- Обеспечение целостности данных при записи.
Недостатки и риски:
- Голодание писателей: При непрерывном потоке читателей писатель может никогда не получить доступ.
- Снижение производительности, если операции чтения короткие, а накладные расходы на управление блокировками высоки.
- Реализация
ReentrantReadWriteLockможет быть нечестной (по умолчанию), что может привести к неопределенному порядку доступа. Честный режим (fair=true) гарантирует порядок, но снижает пропускную способность.