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 thats what I think. I’ve setup a new github repo to put the code to be used in another proyects 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); AtomicInteger readCount = new AtomicInteger(0); public final T read() { T data = null; try { // Entry to read serviceQueueSemaphore.acquire(); readCountSempaphote.acquire(); if (readCount.incrementAndGet() == 1){ resourceSemaphore.acquire(); } serviceQueueSemaphore.release(); readCountSempaphote.release(); // CRITICAL SECTION Do read data = executeReading(); // Exit to read readCountSempaphote.acquire(); if (readCount.decrementAndGet() == 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 pseucode 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
So, guys, what do you think ?