Итак, это классическая проблема параллелизма, с которой мы (я и мой коллега) сталкиваемся здесь. Мы не ленивые, мы принесли соответствующий код, чтобы вы могли нам помочь.
У нас есть два класса, определяющих читателей и писателей, они оба extends класс 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 писателя. Они оба получают один экземпляр класса 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