简体   繁体   中英

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

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 .

这是ReadWriteLock的工作。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM