Deux ponts à sense unique avec un nombre des places limité entre les deux

public class Bridges {                 //two bridges - left and right
    private int engaged,between,places;    //engaged - the vehicles on the bridges going "to between" + "in between"
                                        //places-between, between - vehicles between
    private int nVhOnLeft,nVhOnRight;   // vehicles on the bridges - nVh<0: l->r, nVh>0: r->l
    private boolean closedLeft,closedRight;   // close only the outside entry(left bridge on the left side)
    Bridges(int places){
        this.places=places;
        nVhOnLeft=nVhOnRight=between=engaged=0;
    }
    synchronized public void takeFirst(boolean lr){
        while((nVhOnLeft>0)&& (lr==true)||
                (nVhOnRight<0) && (lr==false)||
                (lr?closedLeft:closedRight)){
            //System.out.println("nVhOnLeft "+nVhOnLeft+"\tlr "+lr+"\tnVhOnRight "+nVhOnRight+"\t"+(closedLeft||closedRight));
            System.out.println("\t"+Thread.currentThread().getName()+" waiting on the first bridge: "+(lr?"Left":"Right"));
            try{     wait();   }
            catch(InterruptedException e){
                System.err.println(e);
            }
        }
        System.out.println(Thread.currentThread().getName()+" on the first bridge: "+(lr?"Left ":"Right "));
        engaged++;
        System.out.println("number of vehicles to enter "+(places-engaged));
        if(engaged>=places){
            closedLeft=true;      
            closedRight=true;
            System.out.println("Close the entry to the bridges");
        }
        if (lr){
            nVhOnLeft--;
        }
        else{
            nVhOnRight++;
        }
        System.out.println("Vehicles: "+nVhOnLeft+" left bridge;\t"+nVhOnRight+" right bridge;\t"+between+" betwеen\n");
       
    }
    synchronized public void takeSec(boolean lr){
        while((nVhOnLeft<0)&& (lr==false)||
                (nVhOnRight>0) && (lr==true)){
            System.out.println("\t"+Thread.currentThread().getName()+" waiting on the second bridge: "+(lr?"Right":"Left"));
            try{     wait();   }
            catch(InterruptedException e){
                System.err.println(e);
            }

        }
        System.out.println(Thread.currentThread().getName()+" on the second bridge: "+(lr?"Right ":"Left "));
        engaged--;
        System.out.println("number of vehicles to enter "+(places-engaged));
        closedLeft=false;      
        closedRight=false;
        System.out.println("The entry to the bridges is open");
        if (lr){
            nVhOnRight--;
        }
        else{
            nVhOnLeft++;
        }
        between--;
        System.out.println("Vehicles: "+nVhOnLeft+" left bridge;\t"+nVhOnRight+" right bridge;\t"+between+" betwеen\n");
        notifyAll();
    }
    synchronized public void leaveFirst(boolean lr){
        if(lr){           //leave the bridge Left in "-> direction"
            nVhOnLeft++;
            System.out.println("\t\t"+Thread.currentThread().getName()+" leave the first bridge: Left ");
        }
        else{           // leave the bridge Right in <- direction
            nVhOnRight--;
            System.out.println("\t\t"+Thread.currentThread().getName()+" leave the first bridge :Right ");
        }
        between++;
        System.out.println("Vehicles: "+nVhOnLeft+" left bridge;\t"+nVhOnRight+" right bridge;\t"+between+" betwеen\n");
        notifyAll();
    }
    synchronized public void leaveSec(boolean lr){
        if(lr){        //leave the the bridge Right
            nVhOnRight++;
            System.out.println("\t\t"+Thread.currentThread().getName()+" leave the second bridge: Right ");
            if(nVhOnRight==0)closedLeft=false;    //no blocking from right
        }
        else{         //leave the bridge left
            nVhOnLeft--;
            System.out.println("\t\t"+Thread.currentThread().getName()+" leave the second bridge :Left ");
            if(nVhOnLeft==0)closedRight=false;    //no blocking from right
        }
        System.out.println("Vehicles: "+nVhOnLeft+" left bridge;\t"+nVhOnRight+" right bridge;\t"+between+" betwеen\n");
        notifyAll();
    }
}


public class Vehicle extends Thread{
    boolean lr;
    Bridges br;
    String name;
    static int num;
    Vehicle(boolean lr, Bridges br){
        this.lr=lr;
        this.br = br;
        name = "V "+ ++num + (lr?" left->":" <-right");
        super.setName(name);
    }
    public void run(){
        br.takeFirst(lr);
        try {
            sleep(1000);
        } catch (InterruptedException e){}
        br.leaveFirst(lr);
       
        br.takeSec(lr);
        try {
            sleep(1000);
        } catch (InterruptedException e){}
        br.leaveSec(lr);
    }
}

public class Circ {
    public static void main(String arg[]){
        Bridges br = new Bridges(4)  ;   
        for(int i = 0; i < 6; i++){
            (new Vehicle(true, br)).start();
            (new Vehicle(false,br)).start();
        }
    }
}