Java StampedLock: what happens to writer while someone is reading

Viewed 200

It's not clear from documentation, what happens to reader and writer threads in case writing tries to occur while readLock is being held.

I'm talking about this timing:

  1. Reader thread (or some reader threads) come and acquires readlock with intention to call some getters on some multi-field object
  2. In the middle of the getters swarm comes the Writer thread and requires the writeLock, and intends to change the object state significantly
  3. Also, more readers come with intention to acquire readlock and call all the getters

So, the questions are:

  • (seems that yes) Is writer thread waiting for all readers from group 1 to call unlockRead(stamp)? So each reader is guaranteed to see consistent state while holding readLock (opposed to tryOptimisticRead -> it's stated that inconsistencies may occur if a writer comes)?

I ran a test with 19 readers and 1 writer, and almost every time it happened that writer thread performed waited for some time before doing it's dummy work. Writers code is below, reader's code is quite similar.

// 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)
}
  • (most surely, yes, but still mentioning) will all readers from group 3 wait for writer to unlockWrite(stamp) ?

So, calling unlockRead(...) has two intentions: protects from deadlocking in same thread, and allows writers to get exclusive writer lock?

Update: here is a video on ReadWriteLock - logic is very similar to stampedlock

1 Answers

Any number of threads can acquire a readLock while no writeLock is being held. As soon as a writing thread is requested three things happen (assuming the readLock is being held by one or more threads)

  1. The writeLock thread is suspended
  2. Any readLock requests from non-read-locking threads are queued up behind the writeLock thread (prevents writer starvation)
  3. Any read-locking threads are able to readLock on the same lock (reentrancy).

Once all readLocks are unlocked then the last thread to unlock will notify/release the thread waiting on the writeLock.

To your questions:

Is writer thread waiting for all readers from group 1 to call unlockRead(stamp)? So each reader is guaranteed to see consistent state while holding readLock (opposed to tryOptimisticRead -> it's stated that inconsistencies may occur if a writer comes)?

Yes, assuming all modifying threads are doing so under a writeLock then while a thread holds a readLock it's safe to assume it wont change.

will all readers from group 3 wait for writer to unlockWrite(stamp) ?

Yes, readLock will block while a writeLock is being held.

Related