How can I make the following parking-lot simulation asynchronous using RabbitMQ?
Tags: rabbitmq, amqp, java, mqp
Published: 2022-06-21 04:13:37

0


I'm trying to learn and undertand the different approaches to concurrency in java. I have with me a serialised implementation of a parking lot simulation. I want to make it so that the program uses Rabbitmq instead, how would I go about doing that?

Below is my parking-lot class, which, implementation wise could also be improved.

EDIT: I've realised that my main question is actually, how can I do the Pub/sub in a loop.2. Is pub/sub even necessary?


`
public class Parking {

    public static void main(String[] args) throws InterruptedException {
        
        Parking parkingObj = new Parking();

        parkingObj.runSimulation();

    }

    public void runSimulation() throws InterruptedException{
        int numOfRuns = 101;//100 runs
        int currentRuns = 1;

        securityGuard myGuard = new securityGuard();

        //spot mySpot = new spot();

        ArrayList<ticketClass> ticketArray = new ArrayList<>();

        int bouncedCustomers = 1;
        spot availableSpot = new spot();

     
        //Random randomExit  = new Random();

        while (currentRuns < numOfRuns){
            Random randomSleep  = new Random();

            //Car object instantiation  
            carClass vehicle = new carClass();
            //ticketClass ticketObj = new ticketClass();
            
            //Random time generator 

            Random randomTime = new Random();


            //instantiation of the info geneatator class

            infoGenerator info = new infoGenerator();


            //Generaring random Car info 

            String plateNumber = info.plateGenerator();
            String carModel = info.modelGenerator();
            String color = info.colorGenerator();

            if (availableSpot.getSpotNum() == 15 ){
                       System.out.println("Carpark full, No cars allowed unitl a space is free");
                       
                       //Customers waiting for free space
                       Thread.sleep(9000);
                       
                       System.out.println("Total Waiting customers: " + bouncedCustomers);

                       bouncedCustomers += 1;

            }
            else{
                
                //System.out.println("Customer Exiting");
                Thread.sleep(randomTime.nextInt(5000));
                
                meterClass myMeter = new meterClass();

                ticketClass myTicket = myGuard.ticketGenerator(vehicle, myMeter);
                //ticketClass myTicket = new ticketClass();
                myTicket.setmeter(myMeter);
                myTicket.setCar(vehicle);
                myTicket.getCar().plateSetter(plateNumber);
                myTicket.getCar().colorSetter(color);
                myTicket.getCar().modelSeter(carModel);
                myTicket.getCar().minSetter(randomTime.nextInt(100));

                //Details are only set if there is space available
                //The assumption is that users cannot stay longer than 2 days. The reality-to-simulation time ratio is 1 unit:10min
                myMeter.setPurchasedMinutes(randomTime.nextInt(72));
                
                
                System.out.println("\n\nCar " + currentRuns + " has entered the car park");
                System.out.println("\nCAR DETAILS:");
                System.out.println(carModel);
                System.out.println(plateNumber);
                System.out.println(color);


                int spotAvail = availableSpot.assignSpot();
               
                myTicket.setSlotNum(spotAvail);

                
                //Set the time the car entered 
                String timeIn = info.timeMonitor();
                
                //myTicket.
                
                
                ticketArray.add(myTicket);
                System.out.println("\n\n===Total customers: " + ticketArray.size());
                
                
                System.out.println(timeIn+"\n");
                
                availableSpot.spotLog();
                
 
            }
            //Cars leaving at random times
            
            for (int i= 0; i < ticketArray.size();i++ ){
                
                    meterClass meterOut =  ticketArray.get(i).getMeter();
                    carClass ExitCar = ticketArray.get(i).getCar();


                    if(myGuard.checkParking(ExitCar,meterOut)){
                        System.out.println("\nCustomer " + ExitCar.plateGetter()+ " is exiting the carpark...");
                        double penaltyVal = ticketArray.get(i).getPenalty();
                        System.out.println("FINE: " + penaltyVal);
                        System.out.println("==================================================================");
                        Thread.sleep(randomTime.nextInt(4000));
                        ticketArray.remove(ticketArray.remove(i));
                        availableSpot.spotFree(i);

                    }
                    
            


            }
            
            

            
        currentRuns += 1;
        
        }
        
        



    }
    
}
`
TLDR: I need to optimise the following code, both structure-wise and in terms of speed (Specifically using multithreading with RabbitMQ)

As it currently is, it runs in an infinite loop, and the fine value is 0. The security guard class which is responsible for this calculation is as such;

public class securityGuard{
        
        public String badgeNumber;
        public String guardName;
        
        securityGuard(){}
        
        securityGuard(String badgeNumber, String guardName){
            
            this.badgeNumber = badgeNumber;
            this.guardName = guardName;           
        }
        
        public void setBadgeNumber(String badgeNumber){
            this.badgeNumber = badgeNumber;
        }
        
        public String getBadgeNumber(){
            
            return badgeNumber;
            
        }
        
        public void setguardName(String guardName){
            this.guardName = guardName;
        }
        
        public String getGuardName(){
            
            return guardName;
            
        }
        
        public boolean checkParking(carClass car,meterClass meter){
            
            return car.minGetter() > meter.getPurchasedMinutes();
        }  
        
        public ticketClass ticketGenerator(carClass car, meterClass meterVar){
            
            ticketClass myTicket = new ticketClass(car,this);
            
            int timeRemaining = car.minGetter() - meterVar.getPurchasedMinutes();
            
            if(checkParking(car,meterVar)){
                if (timeRemaining < 60){
                    myTicket.penalty = 50;
                }
                
                else {
                    myTicket.penalty = 50 + (10 * (timeRemaining/60));
                }
                
            
                
            
            
        }
    return myTicket;
        
   
    }
    
}

Please let me know if you require any additional information regarding the other classes or if I left anything out .Thank you in advance

EDIT:

Below is my attempt at a producer implementation. I tried using a for loop in the run method with the goal of publishing 100 random messages

public class entrySimulation implements Runnable {

    int numOfRuns = 100;//1000 runs
    int currentRuns = 1;

    securityGuard_exp_1 myGuard = new securityGuard_exp_1();


    //System.out.println("Customer Exiting");

    //Thread.sleep(randomTime.nextInt(5000));

    meterClass_exp_1 myMeter = new meterClass_exp_1();
    //Details are only set if there is space available
    //The assumption is that users cannot stay longer than 2 days. The reality-to-simulation time ratio is 1 unit:10min


    //instantiation of the info generator class

    infoGenerator_exp_1 info = new infoGenerator_exp_1();

    //Generating random Car info


    //spot_exp_1 mySpot = new spot_exp_1();
    //Use an iterator
     List<ticketClass_exp_1> ticketArray = new ArrayList<>();

    Iterator<ticketClass_exp_1> iter = ticketArray.iterator();

    public final spot_exp_1 availableSpot = new spot_exp_1();

    //Random time generator
    Random randomTime = new Random();


    public static void main(String[] args) {

        String exchangeName = "entryExchange";
        String routingKey = "exitKey";
        String message = "";

        //Creating a connection factory

        ConnectionFactory factory = new ConnectionFactory();

        //Creating new connection

        try(Connection conVar = factory.newConnection();){

            Channel channelCon = conVar.createChannel();

            //Exchange declaration

            channelCon.exchangeDeclare(exchangeName,"customerExit");



            channelCon.basicPublish(exchangeName,routingKey,null,message.getBytes(StandardCharsets.UTF_8));

            System.out.println("Customer Exited");





        }catch(Exception e){}


    }




    @Override
    public void run() {

        for (int i = 0; i < numOfRuns; i++) {
            //System.out.println(i);


            String plateNumber = info.plateGenerator();
            String carModel = info.modelGenerator();
            String color = info.colorGenerator();

            myMeter.setPurchasedMinutes(randomTime.nextInt(30));


            carClass_exp1_1 vehicle = new carClass_exp1_1(carModel, color, plateNumber, randomTime.nextInt(2880));
            ticketClass_exp_1 myTicket = myGuard.ticketGenerator(vehicle, myMeter);



            //Generating details
            myTicket.setmeter(myMeter);
            myTicket.setCar(vehicle);
            myTicket.getCar().plateSetter(plateNumber);
            myTicket.getCar().colorSetter(color);
            myTicket.getCar().modelSeter(carModel);
            myTicket.getGuard().setguardName("Phill");
            myTicket.getGuard().setBadgeNumber("AF170");
            int spotAvail = availableSpot.assignSpot();
            myTicket.setSlotNum(spotAvail);


            //Set the time the car entered
            String timeIn = info.timeMonitor();


            //message
            System.out.println("\n\nCar " + currentRuns + " has entered the car park");
            System.out.println("\nCAR DETAILS:");
            System.out.println(carModel);
            System.out.println(plateNumber);
            System.out.println(color);
            System.out.println("Penalty" + myTicket.getPenalty());
            ticketArray.add(myTicket);
            System.out.println("============================================|");
            System.out.println("TIME IN: " + timeIn);
            //System.out.println("\n\n===Total customers: " + myTicket.slotNum);



            //message
            availableSpot.spotLog();


            


        }


    }


}

However, I'm not sure how to. Please if anyone can help in any way. Sorry, this is a very new concept to me