使用java信号量解决读写器并发问题
所以,这是我们(我和我的同事)在这里面临的一个经典并发问题。我们并不懒惰,我们带来了一些相关的代码,以便您正确地帮助我们。 我们有两个类来定义reader和writer,它们都扩展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名作者。它们都通过构造函数注入获得数据库类的一个实例。以下是数据库:
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
# 1 楼答案
我实际上没有心情彻底分析您的代码(lazy,我知道:p),但它听起来像java。util。同时发生的locks包几乎有exactly what you need。现在,除非你坚持使用Java1.4,否则我强烈建议你依靠Java并发UTIL来完成这项讨厌的工作。你会让自己更轻松
至于这本书,它看起来像this will fit the bill