I'm learning about threads and synchronization and I'm trying to set up a "phases" system, in which the first phase generates a message(an int for convenience), then passes it on to phase 2, which modifies it(multiplies it by 2), and then passes it on to the last phase which further modifies it and prints it out to console. The problem is that the third phase never gets to run, even though it receives the messages.
In my example I set an array of semaphores called "resources", in which semaphore A(index 0) has 4 permits, semaphore B has 3, and C has 2. All are set to be fair.
I tried setting the Semaphores to be fair, but that didn't fix my issue. I also tried changing the sleep timings but I had no luck.
class Fase1 extends Thread{
private int i = 0;
private Semaphore[] resources;
private Fase2 recipient;
public Fase1(Semaphore[] res, Fase2 fase2){
recipient=fase2;
resources=res;
}
@Override
public void run(){
try{
while(true){
resources[0].acquire(2);
resources[1].acquire(2);
recipient.receiveMessage(i);
i++;
sleep(200);
resources[1].release(2);
resources[0].release(2);
}
} catch (InterruptedException e){
}
}
}
class Fase2 extends Thread{
private Semaphore[] resources;
private Fase3 recipient;
private boolean receivedMessage = false;
private int message = 0;
public Fase2(Semaphore[] res, Fase3 fase3){
recipient=fase3;
resources=res;
}
@Override
public void run(){
try{
while(true){
if(receivedMessage){
resources[0].acquire(2);
resources[1].acquire(2);
resources[2].acquire(2);
recipient.receiveMessage(message*2);
receivedMessage = false;
sleep(200);
resources[2].release(2);
resources[1].release(2);
resources[0].release(2);
}
}
} catch (InterruptedException e){
}
}
public void receiveMessage(int msg){
message = msg;
receivedMessage = true;
}
}
class Fase3 extends Thread{
private Semaphore[] resources;
private boolean receivedMessage = false;
private int message = 0;
public Fase3(Semaphore[] res){
resources=res;
}
@Override
public void run(){
try{
while(true){
if(receivedMessage){
resources[1].acquire(2);
resources[2].acquire(2);
System.out.println(message+1);
receivedMessage = false;
sleep(200);
resources[2].release(2);
resources[1].release(2);
}
}
} catch (InterruptedException e){
}
}
public void receiveMessage(int msg){
message = msg;
receivedMessage = true;
}
}
I noticed that the permits are somehow getting screwed up, it's almost like some of the threads are not releasing them properly, even though it seems right to me.