Java LLD: Designing a Thread-Safe Parking Lot with Strategy Pattern
Designing a parking lot is a staple of Java LLD and machine coding interviews, yet most candidates fail to write production-grade code. As an ex-FAANG interviewer, I've seen countless designs fall apart under concurrent traffic or when asked to support multiple slot allocation algorithms.
If you're prepping for interviews, I've been building javalld.com — real machine coding problems with full execution traces.
The Mistake Most Candidates Make
-
Monolithic locking on the entire
ParkingLotclass: Using a globalsynchronizedkeyword on the entry method, which serializes all gate entries and destroys system throughput. -
Hardcoding slot-finding logic: Mixing spatial layout algorithms (like nearest-to-entrance or smallest-available-fit) directly inside the
ParkingLotorGateclasses, violating the Open-Closed Principle. -
Thread-safety as an afterthought: Relying on raw
List<Slot>iterations without synchronization, causing race conditions where multiple cars are assigned to the exact same physical slot.
The Right Approach
-
Core mental model: Decouple capacity management from slot selection by using a
Semaphorefor gate-keeping and the Strategy Pattern for thread-safe slot allocation. -
Key entities:
ParkingLot,Gate,Slot,Vehicle,ParkingStrategy(SmallestFitStrategy,NearestEntranceStrategy), andStrategyFactory. - Why it beats the naive approach: It isolates concurrency concerns (preventing overbooking) from business rules (how we choose a slot), making the system highly performant and easily extensible.
The Key Insight (Code)
public class EntryGate {
private final Semaphore semaphore;
private final ParkingStrategy strategy;
public EntryGate(int capacity, ParkingStrategy strategy) {
this.semaphore = new Semaphore(capacity);
this.strategy = strategy;
}
public synchronized Ticket park(Vehicle vehicle) {
if (!semaphore.tryAcquire()) throw new ParkingFullException();
Slot slot = strategy.allocateSlot(vehicle);
slot.occupy(vehicle);
return new Ticket(vehicle, slot);
}
}
Key Takeaways
-
Throttle Early with Semaphores: Use a
Semaphoreat the gate level to reject incoming cars instantly when the lot is full, avoiding expensive database or memory lock lookups. -
Strategy Pattern for Allocation: Encapsulate slot-finding algorithms in a
ParkingStrategyinterface, allowing the system to switch behaviors dynamically at runtime. -
Factory Pattern for Instantiation: Leverage a
StrategyFactoryto cleanly instantiate the correct allocation strategy based on the parking lot's operating mode.
Full working implementation with execution trace available at https://javalld.com/problems/parking-lot
Top comments (0)