C'è un oggetto ponte che è condiviso tra 10 thread auto. Il ponte è ad una corsia sola ed ha la capacità di 3 auto per volta(per cui e passano una/due/tre auto da una parte,dall'altra non possono passare). Ogni auto per attraversare il ponte impiega 100 ms. La classe ponte ha due metodi portanti : entra() ed esci().
La prima serve a chiedere l'accesso al ponte e ad attraversarlo, la seconda serve per uscire ed avvertire gli altri di essere usciti. L'auto deve avere due direzioni (nord o sud).
Questo è quello che sono riuscito a fare.
MAIN
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package principale;
/**
*
* @author fabio
*/
public class Principale {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Ponte ponte = new Ponte();
Auto []auto = new Auto[10];
for(int i=0;i<auto.length;i++){
auto[i] = new Auto(ponte);
}
for(int i=0;i<auto.length;i++){
auto[i].start();
}
try{
for(int i=0;i<auto.length;i++){
auto[i].join();
}
}catch(InterruptedException e){
System.out.println(e);
}
}
}
OGGETTO CONDIVISO
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package principale;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
*
* @author fabio
*/
public class Ponte {
ReentrantLock lock;
Semaphore macchine;
Condition autoNord,autoSud;
private int nordIn,sudIn;
private int codaSud,codaNord;
public Ponte(){
this.lock = new ReentrantLock();
this.macchine = new Semaphore(3);
this.autoNord = this.lock.newCondition();
this.autoSud = this.lock.newCondition();
this.nordIn = 0;
this.sudIn = 0;
this.codaNord = 0;
this.codaSud = 0;
}
public void Entra(int direzione){
this.lock.lock();
try{
if(direzione == 0)
{
while(this.sudIn > 0)
{
this.codaNord++;
System.out.println("Auto attende a nord");
this.autoNord.await();
this.codaNord--;
}
this.macchine.acquire();
System.out.println("Auto entra da nord");
this.nordIn++;
}
else
{
while(this.nordIn > 0)
{
this.codaSud++;
System.out.println("Auto attende a sud");
this.autoSud.await();
this.codaSud--;
}
this.macchine.acquire();
System.out.println("Auto entra da sud");
this.sudIn++;
}
}catch(InterruptedException e){
System.out.println(e);
}finally{
this.lock.unlock();
}
}
public void Esci(int direzione){
this.lock.lock();
try{
if(direzione == 0)
{
this.nordIn--;
System.out.println("Auto esce da sud");
this.macchine.release();
if((nordIn == 0) && (codaSud >0))
{
this.autoSud.signalAll();
}
else
if(codaNord >0)
this.autoNord.signal();
}
else
{
this.sudIn--;
System.out.println("Auto esce da nord");
this.macchine.release();
if((sudIn == 0) && (codaNord >0))
{
this.autoNord.signalAll();
}
else
if(codaSud >0)
this.autoSud.signal();
}
}finally{
this.lock.unlock();
}
}
}
THREAD
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package principale;
import java.util.Random;
/**
*
* @author fabio
*/
public class Auto extends Thread{
private Ponte ponte;
Random rnd = new Random();
public Auto(Ponte ponte){
this.ponte = ponte;
}
@Override
public void run(){
int x = rnd.nextInt(2);
this.ponte.Entra(x);
try{
sleep(1);
}catch(InterruptedException e){
System.out.println(e);
}
System.out.println("Provo ad uscire");
this.ponte.Esci(x);
}
}
Il programma gira senza errori. Il problema è che si blocca soltanto nel caso in cui ci sono 3 auto sul ponte che devono uscire, praticamente viene invocato il metodo esci ma il programma si blocca sul lock. Dove sbaglio?