22-Read / Write Locks in Java
- Write Reentrance
- Read to Write Reentrance
- Write to Read Reentrance
- Fully Reentrant ReadWriteLock
- Calling unlock() From a finally-clause
Read / Write Lock Java Implementation
First let's summarize the conditions for getting read and write access to the resource:
Read Access | If no threads are writing, and no threads have requested write access. |
---|---|
Write Access | If no threads are reading or writing. |
//The ReadWriteLock class shown earlier is not reentrant. If a thread that has write access requests it again, it will block because there is already one writer - itself.
public class ReadWriteLock{
private int readers = 0;
private int writers = 0;
private int writeRequests = 0;
public synchronized void lockRead() throws InterruptedException{
while(writers > 0 || writeRequests > 0){
wait();
}
readers++;
}
public synchronized void unlockRead(){
readers--;
notifyAll();
}
public synchronized void lockWrite() throws InterruptedException{
writeRequests++;
while(readers > 0 || writers > 0){
wait();
}
writeRequests--;
writers++;
}
public synchronized void unlockWrite() throws InterruptedException{
writers--;
notifyAll();
}
}
TheReadWriteLock
has two lock methods and two unlock methods. One lock and unlock method for read access and one lock and unlock for write access.
The rules for read access are implemented in thelockRead()
method. All threads get read access unless there is a thread with write access, or one or more threads have requested write access.
The rules for write access are implemented in thelockWrite()
method. A thread that wants write access starts out by requesting write access (writeRequests++
). Then it will check if it can actually get write access. A thread can get write access if there are no threads with read access to the resource, and no threads with write access to the resource. How many threads have requested write access doesn't matter.
It is worth noting that bothunlockRead()
andunlockWrite()
callsnotifyAll()
rather thannotify()
.