Итак, это классическая проблема параллелизма, с которой мы (я и мой коллега) сталкиваемся здесь. Мы не поленились, Мы принесли соответствующий код, чтобы вы могли нам помочь должным образом. У нас есть два класса, определяющих Readers и Writers, они оба расширяют класс Thread и, конечно же, переопределяют метод run следующим образом:
while(!isInterrupted()) {
try{
Thread.sleep(for some time)
}catch(InterruptedException e) {}
database.readLock();
readersWorking++; //for debugging purposes
database.readUnlock();
}
Метод запуска в Writer почти такой же, но мы увеличиваем число 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.