Ответ
Да, работал. ReadWriteLock полезен, когда есть частые операции чтения и редкие — записи. Он позволяет нескольким потокам читать данные одновременно, но блокирует всех читателей и писателей при записи.
Пример:
val lock = ReentrantReadWriteLock()
fun readData() {
lock.readLock().lock()
try {
// чтение данных
} finally {
lock.readLock().unlock()
}
}
fun writeData() {
lock.writeLock().lock()
try {
// запись данных
} finally {
lock.writeLock().unlock()
}
}
Нюансы:
- Может привести к голоданию писателей, если чтение происходит постоянно.
- Не поддерживает обновление блокировки (read → write без отпускания).
- Альтернатива —
StampedLockс оптимистичным чтением.
Ответ 18+ 🔞
Э, слушай, да, работал с этой штукой, ReadWriteLock. Вещь, в принципе, годная, если у тебя схема типичная: данные все читают дохуя раз, а пишут в них редко — как будто последний пряник со стола пытаются урвать.
Представь себе библиотеку, ёпта. Народ (потоки-читатели) может заходить пачками, брать книжки, листать — всем хватает места. Но как только приходит библиотекарь (поток-писатель), чтобы на полку новую партию поставить, он вешает табличку «ИДИТЕ НАХУЙ, ПЕРЕРЫВ», всех выгоняет, делает свои дела, а потом снова всех пускает. Примерно так это и работает.
Вот, смотри, как это в коде выглядит, простейший случай:
val lock = ReentrantReadWriteLock()
fun readData() {
lock.readLock().lock()
try {
// чтение данных
} finally {
lock.readLock().unlock()
}
}
fun writeData() {
lock.writeLock().lock()
try {
// запись данных
} finally {
lock.writeLock().unlock()
}
}
Выглядит вроде логично, да? Но тут, бля, есть подводные камни, о которых голова заболеть может.
Нюансы, на которые надо глаза пялить:
-
Голодание писателей. Это главная беда. Если у тебя читатели ломятся непрерывным потоком — как метро в час пик, — то бедный писатель может ждать своей очереди до второго пришествия. Сидит такой поток, держит в руках свежие данные, а войти не может, потому что читательский замок никогда полностью не отпускается. Картина маслом: обновление никогда не применится. Пиздец, а не ситуация.
-
Нельзя апгрейднуть блокировку. Вот представим: вошёл ты как читатель, посмотрел данные и понял — «ой, а тут надо чутка подправить». Так вот, хуй тебе! Нельзя просто так взять и превратить
readLockвwriteLock. Придётся сначала читательский отпустить, а потом уже писательский брать. А в этот момент между отпусканием и захватом состояние данных могло уже поменяться другим писателем. Получается race condition, волнение ебать. Нужно перепроверять условия — геморрой. -
Есть альтернатива —
StampedLock. Эта штука похитрее будет. У неё есть так называемое «оптимистичное чтение». Ты как бы читаешь данные безо всякого замка, а потом проверяешь, а не пришёл ли пока кто-нибудь и не пописал ли в них. Если нет — красота, работа сделана без лишних блокировок. Если да — тогда уже берёшь полноценную блокировку и перечитываешь. Как лотерея, но часто выигрышная. Только API у него чуть более мозговыносящее.
Короче, инструмент рабочий, но ты его вдумчиво применяй. Если пишешь раз в год, а читают каждую миллисекунду — то самое оно. Если же запись тоже часто нужна, то тут уже надо думать про другие механизмы, а то получишь тормоза и головную боль.