所以,我们(我和我的同事)面临的是一个经典的并发问题。我们不懈努力,为了让您能够正确地帮助我们,我们提供了一些相关代码。 我们有两个类定义读者和写者,它们都扩展Thread类,并且当然重写run方法,如下所示:
while(!isInterrupted()) {
try{
Thread.sleep(for some time)
}catch(InterruptedException e) {}
database.readLock();
readersWorking++; //for debugging purposes
database.readUnlock();
}
作家的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();
}
}
问题:为什么这段代码会导致读者在写者仍在其中,反之亦然时访问数据库?我们如何阻止这种情况发生?我们的逻辑有什么问题?如果有人知道Java并发方面的好书,请推荐一下。
如果提供的代码不足够,请参考完整代码:http://codepad.org/IJ7e145C