Java StampedLock: что происходит с писателем, когда кто-то читает - PullRequest
2 голосов
/ 28 октября 2019

Из документации не ясно, что происходит с потоками чтения и записи, если попытка записи происходит во время удержания readLock.

Я говорю об этом времени:

  1. Поток читателей (или некоторые потоки читателей) приходит и получает блокировку чтения с намерением вызвать некоторые геттеры для какого-либо многопольного объекта
  2. В середине роя геттеров приходит поток Writer, требующий writeLock, и намереваетсязначительно изменить состояние объекта
  3. Кроме того, все больше читателей приходят с намерением получить блокировку чтения и вызвать всех получателей

Итак, вопросы:

  • ( кажется, что да ) Поток писателя ждет, пока все читатели из группы 1 вызовут unlockRead (stamp) ? Таким образом, каждый читатель гарантированно видит непротиворечивое состояние, удерживая readLock (в отличие от tryOptimisticRead -> указано, что несоответствия могут возникать, если приходит писатель)?

Я провел тест с 19 читателями и 1 писателем, и почти каждый раз, когда получалось, что выполняемый поток писателей некоторое время ждал, прежде чем приступить к фиктивной работе. Код писателей приведен ниже, код читателя очень похож.

// lock is a shared StampedLock  
// state is an AtomicBoolean that readers tried to 'dirty read'
def start = currentTimeMillis()
def stamp = lock.writeLock() 
try {
  state.set(!state.get()) 
  def sleepTime = ThreadLocalRandom.current().nextInt(100,200)
  sleep(sleepTime)
  println("WRITER: I waited for ${currentTimeMillis() - start - sleepTime} ms and worked for ${sleepTime}")
} finally {
  lock.unlock(stamp)
}
  • (, конечно, да, но все же с упоминанием ) все читатели из группы 3 будут ждать, пока писатель разблокируетWrite(штамп)?

Итак, вызов unlockRead (...) имеет два намерения: защищает от взаимоблокировки в одном потоке и позволяет авторам получить эксклюзивную блокировку записи?

Обновление: вот видео на ReadWriteLock - логика очень похожа на stampedlock

1 Ответ

2 голосов
/ 28 октября 2019

Любое количество потоков может получить readLock, пока не удерживается writeLock. Как только поток записи запрашивается, происходят три вещи (при условии, что readLock удерживается одним или несколькими потоками)

  1. Поток writeLock приостанавливается
  2. Любые запросы readLock отне блокирующие чтение потоки помещаются в очередь позади потока writeLock (предотвращает голодание писателя)
  3. Любые потоки, блокирующие чтение, могут readLock в той же блокировке (повторный вход).

Как только все readLock разблокированы, последний разблокирующий поток уведомит / освободит поток, ожидающий на writeLock.

На ваши вопросы:

Поток писателя ждет, пока все читатели из группы 1 вызовут unlockRead (stamp)? Таким образом, каждый читатель гарантированно видит непротиворечивое состояние, удерживая readLock (в отличие от tryOptimisticRead -> указано, что несоответствия могут возникать, если приходит писатель)?

Да, при условии, что все модифицирующие потоки делают это под writeLock, тогда, пока поток содержит readLock, можно с уверенностью предположить, что он не изменится.

будетвсе читатели из группы 3 ждут, когда писатель разблокируетWrite (штамп)?

Да, readLock будет блокироваться, пока удерживается writeLock.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...