2
\$\begingroup\$

I've been looking for a solution to the may readers one writer in Java. I was intrigued by this question posted here and I read the Wikipedia entry about it.

So far, I've reached a fine solution, or at least that's what I think. I've set up a new GitHub repo to put the code to be used in another project if people want. But I'm open to improvements and critics if you see fit.

The pseudocode of the main class is here:

abstract class AbsrtactReadersWriter<T> {

Semaphore readCountSempaphote = new Semaphore(1);
Semaphore resourceSemaphore = new Semaphore(1, true);
Semaphore serviceQueueSemaphore = new Semaphore(1,true);
int readCount = 0;


public final T read() {
    T data = null;
    try {
        // Entry to read
        serviceQueueSemaphore.acquire();
        readCountSempaphote.acquire();
        readCount++;
        if (readCount == 1){
            resourceSemaphore.acquire();
        }
        serviceQueueSemaphore.release();
        readCountSempaphote.release();
        // CRITICAL SECTION Do read
        data = executeReading();
        // Exit to read
        readCountSempaphote.acquire();
        readCount--;
        if (readCount == 0){
            resourceSemaphore.release();
        }
        readCountSempaphote.release();
    } catch (InterruptedException e) {
        System.out.println(e.getMessage());
    }
    return data;
  }

// Protected critical section that read the resource
abstract protected T executeReading();


public final void write(T data) {
    try {
        // Entry write
        serviceQueueSemaphore.acquire();
        resourceSemaphore.acquire();
        serviceQueueSemaphore.release();
        // CRITICAL SECTION  Do Write
        executeWriting(data);
        // Exit write
        resourceSemaphore.release();
    } catch (InterruptedException e) {
        System.out.println(e.getMessage());
    }
  }

// Protected critical section that writes to the resource
abstract protected void executeWriting(T data);

}

This pseudocode lacks some elements (privates, comments) form the class on the GitHub repo, but hits the point. In the repo, you can also see examples and tests.

The starvation problem on readers/writer is solved by Java itself, as the semaphores are created with the fair parameter, that forces the fairness of the blocking and a FIFO queue on the waiting threads. I use an AtomicInteger to store the readcount, even it's protected; the equality operation maybe not and doesn't impose a great penalty.

[EDIT1] As suggested by @greybeard I now use an integer and not an AtomicInteger. Code tested and changed into git

\$\endgroup\$
  • \$\begingroup\$ Welcome to Code Review! I find a name like readCountSempaphote unsettling. Using a (java.util.concurrent.?)Semaphore around a (…atomic?)AtomicInteger looks belt and braces. \$\endgroup\$ – greybeard Mar 31 '19 at 23:44
  • \$\begingroup\$ I'll try to use a simple int and see if it works. If that the case, I'll upload the changes and edit the question \$\endgroup\$ – Oscar Besga Panel Apr 2 '19 at 10:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.