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
codice:/* * 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
codice:/* * 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
codice:/* * 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?

Rispondi quotando
