HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

Readers-writers problem using wait notify

Submitted by: @import:stackexchange-codereview··
0
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

Solution

This code in the 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.