Friday, December 03, 2010

Write and read locks in Java

Here's a crude but very transparent way of doing the locking. Note the below code assumes that the implementer will ensure by design that there are NO concurrent writers but concurrent readers i.e., only a single thread will write but multiple threads could read.

int _readers = 0;
boolean _writeWaiting = false;

writeMethod() {

_writeWaiting = true;
boolean canWrite = false;

while (!canWrite) {

synchronized (lock) {

canWrite = _readers > 0 ? false : true;
if (canWrite) {
_writeWaiting = false;
writeToFile;
}
}
}
}

readMethod() {

while (_writeWaiting) {
sleep;
}

synchronized (lock) {
_readers++;
}

readFile;

synchronized (lock) {
_readers--;
}
}

The following code uses Java 1.5 APIs and is a lot more efficient than the above pseudocode. But, it is very opaque. If your JVM implementation has a bug ( and JVMs do have bugs ), the below code could be very tricky to validate and debug.

static ReentrantReadWriteLock _rwl = new ReentrantReadWriteLock();

writeMethod() {

rwl.writeLock().lock();
writeToFile();
rwl.writeLock().unlock();

}

readMethod() {

rwl.readLock().lock();
readFromFile();
rwl.readLock().unlock();

}

Update to post: Edit made on Jan 1, 2011 to clarify the beginning paragraph of this article.

2 comments:

The Sunday Programmer said...

Your pseudo-code is not quite correct. Essentially a single-write-multiple-read lock should prevent the second write. Here you are assuming that there will be no attempt to write a second time while the first is going on which is not valid in most cases.

Victory said...

This is a lock for a special use case that assumes that the implementer will ensure by design that there are no concurrent writers. I should clarify this in the beginning of the post.