Reputation: 376
I have currently created classes such as CarPark, and Floor to represent the car park. I have used an ArrayList of the Floor class to show multiple levels in the car park.
I want to have multiple entries and exits on different floors, equipped with elevators to get from floor to floor.
How should I approach this? I want to be able to add and delete multiple vehicles to the car park when the vehicle enters and leaves at the same time.
How can I use threads and locks in this case?
============== Structure ============
public class CarPark{
private ArrayList<Floor> floorList;
private ArrayList<Vehicle> vehicleList;
}
Methods Implemented:
addVehicle(Vehicle): void
getFreeSlots(): double
deleteVehicle(String): Vehicle
getVehiclePercentages(): HashMap<String, Double>
getOldestVehicle(): Vehicle
getLatestVehicle(): Vehicle
getVehicleById(String): Vehicle
getVehicleByDayYear(String, String): ArrayList
public class Floor implements Comparable<Floor>{
private double maxCapacity;
private double currentCapacity;
private int currentNumberOfVehicles;
private ArrayList<Vehicle> vehicleList;
private ArrayList<VehicleTypes> preferredVehicleType;
private ArrayList<VehicleTypes> possibleVehicleType;
}
Methods Implemented:
Rest are just vehicle classes that will be added to the car park.
Upvotes: 1
Views: 1703
Reputation: 18792
The following mre uses two threads to simulate cars entering and cars leaving. You can control the rate by changing the SLEEP
time:
import java.util.*;
public class CarPark {
private static final int NUM_OF_FLOOORS = 4, SLEEP = 3000;
private final List<Floor> floorList;
public CarPark() {
floorList = Collections.synchronizedList(new ArrayList<>());
for(int i=0; i < NUM_OF_FLOOORS; i++){
floorList.add(new Floor(i));
}
}
private Floor getRandomFloor() {
Collections.shuffle(floorList);
return floorList.get(0);
}
void simulateRandomTraffic(){
simulateRandomEntries();
simulateRandomExits();
}
void simulateRandomEntries(){
new Thread(()->{
while(true){
getRandomFloor().addVehicle(new Vehicle());
try {
Thread.sleep(SLEEP);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}).start();
}
void simulateRandomExits(){
new Thread(()->{
while(true){
getRandomFloor().removeRandomVehicle();
try {
Thread.sleep(SLEEP);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}).start();
}
public static void main(String[] args) {
new CarPark().simulateRandomTraffic();
}
}
class Floor{
private final double maxCapacity = 100;
private final List<Vehicle> vehicleList;
private final int floorNumber;
public Floor(int floorNumber) {
this.floorNumber = floorNumber;
vehicleList = Collections.synchronizedList(new ArrayList<>());
}
public int getCurrentNumberOfVehicles() {
return vehicleList.size();
}
public boolean isFull(){
return maxCapacity <= getCurrentNumberOfVehicles();
}
public boolean isEmpty(){
return getCurrentNumberOfVehicles() <= 0;
}
public int getFloorNumber() {
return floorNumber;
}
private Vehicle getRandomVehicle() {
Collections.shuffle(vehicleList);
return vehicleList.get(0);
}
public boolean removeRandomVehicle(){
if(isEmpty()) {
System.err.println("Floor "+ getFloorNumber()+" is empty. Can't remove vehicle");
return false;
}
return removeVehicle(getRandomVehicle());
}
public boolean addVehicle(Vehicle v){
if(isFull()) {
System.err.println("Floor "+ getFloorNumber()+" is full. Can't add vehicle");
return false;
}
vehicleList.add(v);
System.out.println("Floor "+ getFloorNumber()+" vehicle added ("+ getCurrentNumberOfVehicles()+"/"+maxCapacity+")");
return true;
}
public boolean removeVehicle(Vehicle v){
if(isEmpty()) {
System.err.println("Floor "+ getFloorNumber()+" is empty. Can't remove vehicle");
return false;
}
vehicleList.remove(v);
System.out.println("Floor "+ getFloorNumber()+" vehicle removed ("+ getCurrentNumberOfVehicles()+"/"+maxCapacity+")");
return true;
}
}
class Vehicle{}
The next enhancement is a car park Queue
.
Have a third thread push cars into the Queue
(or multiple queses, one for each entrance, all filled by the same thread).
Have simulateRandomEntries()
pull from the queue (or queues) and push to a random floor.
Upvotes: 4
Reputation: 51455
The basis of any simulation, or game, is a game loop. This is a loop that runs for a certain period of time.
In Java, you can use a Runnable added to a Thread to run a simulation loop.
Here's an example Runnable
.
public class SimulationRunnable implements Runnable {
/** Simulation run time, in minutes */
private final int duration;
private final Random random;
private final SimulationView view;
private final SimulationModel model;
public SimulationRunnable(SimulationView view, SimulationModel model,
int duration) {
this.view = view;
this.model = model;
this.duration = duration;
this.random = new Random();
}
@Override
public void run() {
int iterations = duration * 60 * 5;
for (int index = 0; index < iterations; index++) {
// Update simulation model
// We will add cars for the first 10 hours (minutes)
if (index < iterations - 600) {
for (int jndex = 0; jndex < 5; jndex++) {
if (random.nextInt(10) == 5) {
// Add car
}
}
}
// We will remove cars for the last 10 hours (minutee)
if (index > 600) {
for (int jndex = 0; jndex < 5; jndex++) {
if (random.nextInt(10) == 3) {
// Remove car
}
}
}
// Report status every 300 iterations
if (index % 300 == 0) {
}
// Pause simulation loop
try {
Thread.sleep(200L);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
To start the simulation, you create a Thread
using the Runnable
.
new Thread(new SimulationRunnable(view, model, 12)).start();
Let's assume you want to simulate a 12 hour period where cars enter and leave the parking lot. One possible simulation could be:
Let's also assume that the simulation timer runs as one minute representing one hour. So the simulation will run for 12 minutes.
Let's also assume that the simulation loop runs five times a second. That means the simulation loop will execute once every 200 milliseconds, for a total of 3,600 executions.
Now all you have to do is decide how many cars enter the parking lot per hour and how many cars leave the parking lot per hour. The rates should be pretty close to one another.
Too many cars entering the parking lot per hour will fill the lot.
Too few cars entering the parking lot per hour will leave the lot mostly empty.
The game loop will update your simulation model. Every so often, say every game hour (minute) you report the status of your parking lot.
Upvotes: 1