patternjavaModerate
Readers-writers problem using wait notify
Viewed 0 times
notifyproblemwaitwritersreadersusing
Problem
Description of the Readers–writers problem.
It looks like it works, but I have some doubts:
```
class ReadWriteBuffer {
private static final Object writeLock = new Object();
private static final Object readWriteLock = new Object();
private int numberReaders = 0;
private int numberWriters = 0;
private int numberWriteRequests = 0;
public void write(T object) throws InterruptedException {
numberWriteRequests++;
synchronized (readWriteLock) {
while (numberReaders > 0) {
readWriteLock.wait();
}
}
synchronized (writeLock) {
numberWriteRequests--;
numberWriters++;
System.out.println("Writer #" + Thread.currentThread().getId() + " started writing.");
Thread.sleep(3000);
System.out.println("Writer #" + Thread.currentThread().getId() + " finished writing.");
numberWriters--;
synchronized (readWriteLock) {
readWriteLock.notifyAll();
}
}
}
public void read() throws InterruptedException {
synchronized (readWriteLock) {
while (numberWriters > 0 || numberWriteRequests > 0) {
readWriteLock.wait();
}
}
numberReaders++;
System.out.println("Reader #" + Thread.currentThread().getId() + " started reading.");
Thread.sleep(1000);
System.out.println("Reader #" + Thread.currentThread().getId() + " finished reading.");
numberReaders--;
synchronized (readWriteLock) {
readWriteLock.notifyAll();
}
}
}
class Reader implements Runnable {
private final ReadWriteBuffer buffer;
private int priority;
public Reader(int priority, ReadWriteBuffer buffer) {
this.priority = priority;
this.buffer = buffer;
}
@Override
public void run() {
while (true) {
try {
T
It looks like it works, but I have some doubts:
```
class ReadWriteBuffer {
private static final Object writeLock = new Object();
private static final Object readWriteLock = new Object();
private int numberReaders = 0;
private int numberWriters = 0;
private int numberWriteRequests = 0;
public void write(T object) throws InterruptedException {
numberWriteRequests++;
synchronized (readWriteLock) {
while (numberReaders > 0) {
readWriteLock.wait();
}
}
synchronized (writeLock) {
numberWriteRequests--;
numberWriters++;
System.out.println("Writer #" + Thread.currentThread().getId() + " started writing.");
Thread.sleep(3000);
System.out.println("Writer #" + Thread.currentThread().getId() + " finished writing.");
numberWriters--;
synchronized (readWriteLock) {
readWriteLock.notifyAll();
}
}
}
public void read() throws InterruptedException {
synchronized (readWriteLock) {
while (numberWriters > 0 || numberWriteRequests > 0) {
readWriteLock.wait();
}
}
numberReaders++;
System.out.println("Reader #" + Thread.currentThread().getId() + " started reading.");
Thread.sleep(1000);
System.out.println("Reader #" + Thread.currentThread().getId() + " finished reading.");
numberReaders--;
synchronized (readWriteLock) {
readWriteLock.notifyAll();
}
}
}
class Reader implements Runnable {
private final ReadWriteBuffer buffer;
private int priority;
public Reader(int priority, ReadWriteBuffer buffer) {
this.priority = priority;
this.buffer = buffer;
}
@Override
public void run() {
while (true) {
try {
T
Solution
This code in the
Since
Additionally, they may not produce the right results, anyway. The
Bottom line is that, from a multi-threaded perspective, this code is broken.
References:
read() method is broken:public void read() throws InterruptedException {
synchronized (readWriteLock) {
while (numberWriters > 0 || numberWriteRequests > 0) {
readWriteLock.wait();
}
}
numberReaders++;
System.out.println("Reader #" + Thread.currentThread().getId() + " started reading.");
Thread.sleep(1000);
System.out.println("Reader #" + Thread.currentThread().getId() + " finished reading.");
numberReaders--;
synchronized (readWriteLock) {
readWriteLock.notifyAll();
}
}Since
numberReaders ++ and -- is not in a synchronized block, it essentially may as well not happen as far as other threads are concerned, or, worse, it could partially happen (like the ++ may happen, and the -- may not).Additionally, they may not produce the right results, anyway. The
++ operator is not atomic, and it is possible for the value to be ++ in two different threads at the same time, and the result to be just one increment for both invocations.Bottom line is that, from a multi-threaded perspective, this code is broken.
References:
- Is the pre-incriment operator thread-safe?
- Java Concurrency in Practice (read this if you can)
- Java's
ReadWriteReentrantLock
Code Snippets
public void read() throws InterruptedException {
synchronized (readWriteLock) {
while (numberWriters > 0 || numberWriteRequests > 0) {
readWriteLock.wait();
}
}
numberReaders++;
System.out.println("Reader #" + Thread.currentThread().getId() + " started reading.");
Thread.sleep(1000);
System.out.println("Reader #" + Thread.currentThread().getId() + " finished reading.");
numberReaders--;
synchronized (readWriteLock) {
readWriteLock.notifyAll();
}
}Context
StackExchange Code Review Q#59928, answer score: 11
Revisions (0)
No revisions yet.