所以,这是我们(我和我的同事)面临的经典并发问题。我们并不懒惰,我们带来了一些相关的代码,以便您正确地帮助我们。 我们有两个定义读者和写作者的类,它们都扩展 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
答案 0 :(得分:5)
我实际上并不想彻底分析你的代码(懒惰,我知道:p),但听起来java.util.concurrent.locks包几乎有exactly what you need。现在,除非你坚持使用Java 1.4,否则我强烈建议依靠Java并发工具来为你做这个讨厌的工作。你会让自己更轻松。
至于这本书,它看起来像this will fit the bill。
答案 1 :(得分:1)
这是ReadWriteLock的作业。