This is a standard interview question when it comes to testing a candidate’s java oops and multi-threading knowledge. The solution I am providing is nowhere near perfect and can be implemented in several different ways but its a starting point in which anyone can build upon.
Problem Statement :-
We have a parking space which has limited parking spots for two wheeler vehicles and four wheeler vehicles. We have to implement a system wherein cars/bikes can park or leave in a multi threaded environment using OOPs methodologies.
Here is a simple solution i propose :-
Have an interface Vehicle which will be implemented by both TwoWheeler and FourWheeler vehicles which will have no method declarations. It will just be a way to separate the type of vehicles for logical separation.
interface Vehicle { } class TwoWheeler implements Vehicle { } class FourWheeler implements Vehicle { }
Let’s assume there are 10 spots for two wheeler and four wheeler vehicles. Monitor Lock will be a simple object and two active counts for each type of vehicle.
private final int TWO_WHEELER_PARKING = 10; private final int FOUR_WHEELER_PARKING = 10; private final Object lock = new Object(); private int twoWheelerCount = 0; private int fourWheelerCount = 0;
Let’s implement the parking and leaving methods for vehicles. To gaurantee visibility gaurantees, atomicity; we will be using synchronized blocks which will lock on the simple object we created earlier.
Randomized integers will decide the type of vehicle, whether they are going to park or leave and run these methods indefinitely.
Parking will increment the active count based on the vehicle type and leave will decrement the count if its greater than 0.
public void park(Vehicle vehicle) { synchronized (lock) { if (vehicle instanceof FourWheeler && fourWheelerCount < FOUR_WHEELER_PARKING) { fourWheelerCount++; System.out.println(vehicle.getClass().getSimpleName() + " parked. Four wheeler count: " + fourWheelerCount); } else if (vehicle instanceof TwoWheeler && twoWheelerCount < TWO_WHEELER_PARKING) { twoWheelerCount++; System.out.println(vehicle.getClass().getSimpleName() + " parked. Two wheeler count: " + twoWheelerCount); } else { System.out.println(vehicle.getClass().getSimpleName() + " parking not available."); } } } public void leave(Vehicle vehicle) { synchronized (lock) { if (vehicle instanceof FourWheeler && fourWheelerCount > 0) { fourWheelerCount--; System.out.println(vehicle.getClass().getSimpleName() + " left. Four wheeler Count: " + fourWheelerCount); } else if (vehicle instanceof TwoWheeler && twoWheelerCount > 0) { twoWheelerCount--; System.out.println(vehicle.getClass().getSimpleName() + " left. Two wheeler Count: " + twoWheelerCount); } } }
Lastly, Lets implement the main method to use the parking system concurrently.
As I am using Java 21, I am using virtual threads; you can implement the same using standard threads.public class Main { public static void main(String[] args) { ParkingSystem parkingSystem = new ParkingSystem(); while (true) { Random random = new Random(); int randomVehicleSelector = random.nextInt(0, 2); int randomActionSelector = random.nextInt(0, 2); int randomSleep = random.nextInt(0, 2); try { TimeUnit.SECONDS.sleep(randomSleep); switch (randomVehicleSelector) { case 0 -> { if (randomActionSelector == 0) { Thread.ofVirtual().start(() -> parkingSystem.park(new FourWheeler())); } else { Thread.ofVirtual().start(() -> parkingSystem.park(new TwoWheeler())); } } case 1 -> { if (randomActionSelector == 0) { Thread.ofVirtual().start(() -> parkingSystem.leave(new FourWheeler())); } else { Thread.ofVirtual().start(() -> parkingSystem.leave(new TwoWheeler())); } } default -> {} } } catch (InterruptedException e) { e.printStackTrace(); } } } }
This will start the parking/leaving of vehicles indefinitely maintaining thread safety and introducing a random aspect to the application.
Source Code can be found here :-
https://github.com/Huzaifa666/MultiThreading_Java/blob/master/src/main/java/org/concurrency/Main.java
That’s it for now.
Stay tuned for more such content.