使用java信号量解决读者/写作者

nul*_*ent 3 java concurrency semaphore

所以,这是我们(我和我的同事)面临的经典并发问题.我们并不懒惰,我们提供了一些相关的代码,以便您正确地帮助我们.我们有两个定义Readers和Writers的类,它们都扩展了 Thread类,当然也会覆盖run方法,如下所示:

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

 database.readLock();
  readersWorking++; //for debugging purposes
 database.readUnlock();
}
Run Code Online (Sandbox Code Playgroud)

Writer的run方法几乎相同,但我们正在增加writersWorking,也用于调试目的.

在我们的主要方法中,我们创建了20个读者和2个作者.他们都通过构造函数注入获得一个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();
    }
}
Run Code Online (Sandbox Code Playgroud)

问题:为什么这些代码会导致我们的读者访问数据库而Writers仍在其中,反之亦然?我们怎么能否认这种情况发生?我们的逻辑出了什么问题?如果有人知道的话,我们也在寻找一本关于Java并发性的好书.

如果提供的代码不够,这里是完整的代码:http://codepad.org/IJ7e145C

G_H*_*G_H 5

我实际上并不想彻底分析你的代码(懒惰,我知道:p),但听起来java.util.concurrent.locks包几乎完全符合你的需要.现在,除非你坚持使用Java 1.4,否则我强烈建议依靠Java并发工具来为你做这个讨厌的工作.你会让自己更轻松.

至于这本书,看起来这符合法案.