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:
- Reader thread (or some reader threads) come and acquires readlock with intention to call some getters on some multi-field object
- In the middle of the getters swarm comes the Writer thread and requires the writeLock, and intends to change the object state significantly
- 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