Un ponte contiene una sola corsia di traffico consentendo così l'accesso a macchine provenienti da una sola direzione per volta, a senso unico alternato. Si identifichi ciascuna macchina con un processo (ci saranno quindi due tipi di processo, le macchine provenienti da nord e le macchine provenienti da sud) e si scriva un programma che sincronizzi l'accesso delle auto sul ponte, facendo uso dei costrutti monitor e regioni
critiche condizionali.Si tenga conto che:
non esistono priorità tra i processi;
un processo può attraversare il ponte solo se non vi sono sopra processi dell'altro tipo.


THREAD2
codice:
package strada;

/**

 */
public class Sud extends Thread{
   
    private Ponte ponte;
    
    public Sud(Ponte ponte){
        this.ponte=ponte;
    }
    
    @Override
    public void run(){
        System.out.println("Auto sud vuole entrare");
        ponte.EntraSud();
        try{
            sleep(2);
        }catch(InterruptedException e){
            System.out.println(e);
        }
        ponte.EsciSud();
        
    }
}

THREAD 1
codice:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package strada;

/**

public class Nord extends Thread{
    private Ponte ponte;
    
    public Nord(Ponte ponte){
        this.ponte=ponte;
    }
    
    @Override
    public void run(){
        System.out.println("Auto nord vuole entrare");
        ponte.EntraNord();
        try{
            sleep(2);
        }catch(InterruptedException e){
            System.out.println(e);
        }
        ponte.EsciNord();
        
    }
    
}
OGGETTO CONDIVISO
codice:
/*

 */
package strada;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 *
 
 */
public class Ponte {
    ReentrantLock lock;
    Condition nord,sud;
    private int NordIn=0;
    private int SudIn=0;
    
    public Ponte(){
        this.lock=new ReentrantLock();
        this.nord =this.lock.newCondition();
        this.sud =this.lock.newCondition();
    }
    
    public void EntraNord(){
        this.lock.lock();
        try{
            while(SudIn>0)
                this.nord.await();
            System.out.println("Auto nord attraversa il ponte");
            NordIn++;
            
        }catch(InterruptedException e ){
            System.out.println(e);
        }finally{
            this.lock.unlock();
        }
    }
    
    public void EntraSud(){
        this.lock.lock();
        try{
            while(NordIn>0)
                this.sud.await();
            System.out.println("Auto sud attraversa il ponte");
            SudIn++;
            
        }catch(InterruptedException e ){
            System.out.println(e);
        }finally{
            this.lock.unlock();
        }
    }
    
    public void EsciNord(){
        this.lock.lock();
        try{ 
            System.out.println("Auto esce da nord");
            NordIn--;
            if(NordIn==0)
                this.sud.signal();
                     
        }finally{
            this.lock.unlock();
        }
    }
    
    public void EsciSud(){
        this.lock.lock();
        try{ 
            System.out.println("Auto esce da sud");
            SudIn--;
            if(SudIn==0)
                this.nord.signal();
                      
        }finally{
            this.lock.unlock();
        }
    }
    
}

MAIN
codice:
package strada;

/**

 */
public class Strada {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        Ponte ponte = new Ponte();
        Sud []sud = new Sud[10];
        Nord []nord = new Nord[10];      
        
        for(int i=0;i<10;i++)
        {
           sud[i]= new Sud(ponte);
           nord[i] = new Nord(ponte);
        }
        
        for(int i=0;i<10;i++)
        {
           sud[i].start();
           nord[i].start();
        }
        
        for(int i=0;i<10;i++)
        try{
           sud[i].join();
           nord[i].join();
        }catch(InterruptedException e){
            System.out.println(e);
        }
        
    }
}

Questo è il mio programma.
Sembra funzionare tutto. Il problema è nel finale quando il programma rimane in running senza bloccarsi. Dove sbaglio?