DEV Community

Daiiszuki
Daiiszuki

Posted on

How can I make the following parking-lot simulation asynchronous using RabbitMQ?

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;

    }





}
Enter fullscreen mode Exit fullscreen mode

}
`
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;


}
Enter fullscreen mode Exit fullscreen mode

}

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();





    }


}
Enter fullscreen mode Exit fullscreen mode

}

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

Top comments (0)