Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Solving Readers/Writers using java Semaphores

So, it's a classical concurrency problem we're (Me and my colleague) facing here. We weren't lazy, We brought some relevant code in order for you to help us properly. We have two classes defining Readers and Writers, they both extend Thread class, and of course override the run method like so:

while(!isInterrupted()) {
 try{ 
     Thread.sleep(for some time)
 }catch(InterruptedException e) {}

 database.readLock();
  readersWorking++; //for debugging purposes
 database.readUnlock();
}

Writer's run method is pretty much the same, but we're incrementing writersWorking, also for debugging purposes.

In our main method we're creating 20 readers and 2 writers. They both get one instance of Database class via constructor injecting. Here is the Database:

class Database {
    Semaphore writeMut = new Semaphore(1);
    Semaphore readMut = new Semaphore(1);
    private int readersWorking = 0;

    public Database() {

    }

    public void readLock() {
        readMut.acquireUninterruptibly();

        if(readersWorking==0) //Am I the first one?
            writeMut.acquireUninterruptibly();
        readersWorking++;

        readMut.release();
    }

    public void writeLock() {
        writeMut.acquireUninterruptibly();
    }

    public void readUnlock() {
        readMut.acquireUninterruptibly();
        readersWorking--;
        if(readersWorking==0) //Am I the last one?
            writeMut.release();
        readMut.release();
    }

    public void writeUnlock() {
        writeMut.release();
    }
}

The question: why does this code result in our Readers accessing the database while the Writers are still in it and vice versa? How can we deny this from happening? What is wrong with our logic here? We're also looking for a good book on concurrency in Java, if anyone knows such.

Just in case the code provided isn't enough, here's the full code: http://codepad.org/IJ7e145C

like image 287
nullpotent Avatar asked Aug 29 '26 12:08

nullpotent


1 Answers

I'm not actually in the mood to thoroughly analyze your code (lazy, I know :p), but it sounds like the java.util.concurrent.locks package has pretty much exactly what you need. Now unless you're stuck with Java 1.4 I'd strongly suggest relying on the Java concurrency utils to do this nasty work for you. You'll make it easier on yourself.

As for the book, it looks like this will fit the bill.

like image 158
G_H Avatar answered Sep 01 '26 00:09

G_H



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!