Careeroza
Real World Example
IRCTC-style Seat Booking
When thousands of users try to book the last seats on a train at 10 AM tatkal time, the seat count must never go below zero. Each booking is a check-then-act operation that must be atomic.
Example
8 threads (users) try to book 3 seats each from a coach with 20 seats. With synchronized, exactly 20 seats are sold and no seat is double-booked.
import java.util.*;
public class Main {
public static void main(String[] args) throws InterruptedException {
Coach coach = new Coach(20);
int[] booked = new int[8];
List<Thread> users = new ArrayList<>();
for (int u = 0; u < 8; u++) {
final int user = u;
Thread t = new Thread(() -> {
for (int i = 0; i < 3; i++) if (coach.bookSeat()) booked[user]++;
});
users.add(t);
t.start();
}
for (Thread t : users) t.join();
int totalBooked = Arrays.stream(booked).sum();
System.out.println("Seats booked: " + totalBooked);
System.out.println("Seats left: " + coach.available());
System.out.println("Oversold? " + (totalBooked > 20));
}
}
class Coach {
private int available;
Coach(int seats) { this.available = seats; }
synchronized boolean bookSeat() {
if (available > 0) { // check
available--; // act — atomic together under the lock
return true;
}
return false;
}
synchronized int available() { return available; }
}Output
Seats booked: 20 Seats left: 0 Oversold? false
In Production
A single JVM lock only protects one server. Real booking systems run many instances, so they also use the database for safety: UPDATE seats SET available = available - 1 WHERE train_id = ? AND available > 0 (atomic in the DB), optimistic locking with a @Version column, or a distributed lock in Redis.