Skip to content

Instantly share code, notes, and snippets.

@nsivabalan
Created December 19, 2013 06:27
Show Gist options
  • Select an option

  • Save nsivabalan/8035183 to your computer and use it in GitHub Desktop.

Select an option

Save nsivabalan/8035183 to your computer and use it in GitHub Desktop.
No Starvation Reader Writer
public class NoStarveReaderWriterLock {
private final Semaphore readMutex = new Semaphore(1);
private final Semaphore writeMutex = new Semaphore(1);
private final Semaphore noStarveMutex = new Semaphore(1);
private final Set<Long> readerIds = Collections
.synchronizedSet(new HashSet<Long>());
private volatile Long writerId;
public void readLock() {
try {
noStarveMutex.acquire();
noStarveMutex.release();
readMutex.acquire();
readerIds.add(Thread.currentThread().getId());
if (readerIds.size() == 1) {
writeMutex.acquire();
}
} finally {
readMutex.release();
}
}
public void readUnlock() {
try {
readMutex.acquire();
long threadId = Thread.currentThread().getId();
if (!readerIds.contains(threadId)) {
throw new IllegalStateException(
String.format(
"The current thread with id: %d never acquired a read lock before.",
threadId));
}
readerIds.remove(threadId);
if (readerIds.size() == 0) {
writeMutex.release();
}
} finally {
readMutex.release();
}
}
public void writeLock() {
noStarveMutex.acquire();
writeMutex.acquire();
writerId = Thread.currentThread().getId();
}
public void writeUnlock() {
Long threadId = Thread.currentThread().getId();
if (writerId == null || !writerId.equals(threadId)) {
throw new IllegalStateException(
String.format(
"The current thread with id: %d never acquired a write lock before.",
threadId));
}
noStarveMutex.release();
writeMutex.release();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment