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

时间:2011-11-14 16:14:21

标签: java concurrency semaphore

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

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

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

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();
    }
}

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

如果提供的代码不够,请输入完整的代码:http://codepad.org/IJ7e145C

2 个答案:

答案 0 :(得分:5)

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

至于这本书,它看起来像this will fit the bill

答案 1 :(得分:1)

这是ReadWriteLock的作业。