I am trying to implement the problem of readers and writers in Java, and for this I am based on the method used by Tanenbaum in the book of Operating Systems. With only one thread writer and one thread reader the program works fine, the problem is that when I create more than one thread reader the program goes into an infinite loop type and stops printing on the screen. Could you tell me where the problem is?
public class Principal {
public static void main(String[] args) {
Semaphore mutex = new Semaphore(1);
Semaphore db = new Semaphore(1);
int rc = 0;
Escritores e1 = new Escritores(db, mutex);
Leitores l1 = new Leitores(db, mutex, rc);
Leitores l2 = new Leitores(db, mutex, rc);
e1.start();
l1.start();
l2.start();
}
}
public class Escritores extends Thread {
Semaphore db;
Semaphore mutex;
int rc;
public Escritores(Semaphore db, Semaphore mutex){
this.db = db;
this.mutex = mutex;
}
public void run(){
while(true){
try {
Thread.sleep(this.aleatoriar(0, 100));
this.db.acquire();
System.out.println("Escreveu!");
this.db.release();
} catch (InterruptedException ex) {
Logger.getLogger(Escritores.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public int aleatoriar(int minimo, int maximo) {
Calendar lCDateTime = Calendar.getInstance();
return (int)(lCDateTime.getTimeInMillis() % (maximo - minimo + 1) + minimo);
}
}
public class Leitores extends Thread {
Semaphore db;
Semaphore mutex;
int rc;
public Leitores(Semaphore db, Semaphore mutex, int rc){
this.db = db;
this.mutex = mutex;
this.rc = rc;
}
public void run(){
while(true){
try {
Thread.sleep(this.aleatoriar(0, 100));
this.mutex.acquire();
this.rc = this.rc + 1;
if(this.rc == 1){
this.db.acquire();
}
this.mutex.release();
System.out.println("Leu");
this.mutex.acquire();
this.rc = this.rc - 1;
if(this.rc == 0){
this.db.release();
}
this.mutex.release();
} catch (InterruptedException ex) {
Logger.getLogger(Leitores.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public int aleatoriar(int minimo, int maximo) {
Calendar lCDateTime = Calendar.getInstance();
return (int)(lCDateTime.getTimeInMillis() % (maximo - minimo + 1) + minimo);
}
}