SwadhyAI Notes

All Low-Level Design notes

Concurrency · LLD

Race conditions in object design

A race condition happens when two threads read and write shared state, and the result depends on timing. Example: Gate A looks at the board — spot 101 is free. Gate B looks a moment later — spot 101 is still free. Both print a ticket. Two cars drive into one rectangle of concrete.

A is that story: two actors, one piece of , and a gap between “I looked” and “I wrote.” Name those two steps before you type a Java keyword.

The board after Saturday

1

Spot 101

Occupied. Last write won. Looks fine.

2

Ticket T-1

Gate A issued it. Driver A has a slip.

3

Ticket T-2

Gate B issued it. Driver B has a slip.

4

The damage

Two tickets. One spot. A lost update.

The real question

What is the shared state, and which two steps can both gates do at the same time?

If you answer “I need synchronized,” you skipped the question. The interviewer is grading whether you can point at occupancy, not whether you remember a monitor.

Walk the interleaving

One history, two tickets

Draw this on the whiteboard. is not a Java topic. It is the only way to prove the bug exists.

  1. T0

    Board

    Spot 101 is FREE. No ticket yet.

  2. T1

    Gate A

    isFree(101)? YES. Decision pending. Hand still empty.

  3. T2

    Gate B

    isFree(101)? YES. Same snapshot. Same decision pending.

  4. T3

    Gate A

    occupy(101). Issue T-1. Car A rolls in.

  5. T4

    Gate B

    occupy(101). Issue T-2. Car B has nowhere to stand.

The last write left the board looking honest. The is the extra ticket, not a torn boolean.

Name the shared data before the tool

Spot occupancy is the fact. Not the ticket paper. Not the fee. Not the SMS. If you lock the printer, both gates still read FREE. The is “read free, then write occupied.” That pair is one decision. Split it, and Saturday evening invents a second car for 101.

This is . You will meet it again as “if the seat is open, hold it,” “if the key is missing, put it,” “if the ticket is ACTIVE, mark PAID.” The English is one sentence. The machine is two steps.

01

Name the fact

Spot 101’s occupancy. Say it out loud. If you cannot, you will protect the wrong object.

02

Name the two steps

Read free. Write occupied. Draw the gap. Invite the other gate into the gap.

03

Then pick a tool

CAS, a lock, or one thread that owns all spots. Story first. Java second.

The same race in other LLD problems

Once you can tell the two-gate story, you can smell it in a movie hall, a cache, and a cashier pair. The domain nouns change. The gap does not.

Movie ticket

Two counters both see seat H12 free. Both hold it. Both print. One seat. Two barcodes. Shared state is the seat, not the printer.

In-process cache

Two gets miss. Both load. Both insert. Recency list grows two nodes for one key. Shared state is the map plus the list, not the value bytes.

Ticket pay

Two cashiers read ACTIVE. Both mark PAID. Both open the till. The car left once. Shared state is the status arrow, not the cash drawer.

Inventory pick

Two orders read quantity 1. Both decrement to 0. Two shipments. Shared state is the count, not the packing slip.

The two-step bug, in Java

Reason first: the methods below are honest English. They are not one decision. After you can say that, the code is just the same story typed.

java
class ParkingSpot {
  private boolean occupied = false;

  boolean isFree() { return !occupied; }

  void occupy() { occupied = true; }   // too late — the check already raced
}

// Gate A and Gate B both do this:
if (spot.isFree()) {
  spot.occupy();
  return issueTicket(spot);            // two tickets for 101
}

isFree plus occupy is the diagnosis. A lock around issueTicket does not close the gap. Neither does making occupied volatile — that is a visibility story, not an atomic occupy. Those pages come next; this page stops at naming the race.

Diagnosis is not a keyword

How to explain this in an interview

“Two gates, one spot, check-then-act. I will make occupy one step, or give one thread the board.”

Avoid this

“I’ll put synchronized on ParkingLot.” That may be a later fix. It is not the bug. The bug is the gap.

Three honest fixes exist. An atomic transition on the spot. A lock around pick-and-occupy. Confinement: one allocator thread owns the whiteboard. Pick after you can tell the story. Do not start with ReentrantLock because it sounds grown-up.

Interview flow

Drive the round from the story

  1. 1Clarify: two gates may park at once, or is this a single-thread sketch first?
  2. 2Name occupancy as shared mutable state. Point at the field, not “the lot.”
  3. 3Walk T1–T4. Ask whether two tickets is unacceptable. It always is.
  4. 4Offer a mechanism only after the interviewer nods at the race.

Common mistakes

Calling it a missing synchronized

The bug is check-then-act on shared occupancy. A lock is one fix. It is not the diagnosis. Say the two steps first.

Protecting the wrong object

Synchronizing the receipt printer leaves the spot board open. Two gates can still both read FREE. Lock, or CAS, the occupancy decision.

Trusting a main-method demo

One thread never interleaves with itself. park() looking fine in a loop does not mean two gates cannot both take 101.

Where the design still breaks

Fixing occupy on one spot does not fix “pick a free compact among twenty.” Two gates can both choose 101 before either marks it, if pick and occupy are still split across the list. Either lock the pick, or make each tryOccupy fail cleanly so the loser walks to 102. That choice is the optimistic-versus-pessimistic page.

Exercises

  1. Write the T0–T4 interleaving for two cashiers paying the same ACTIVE ticket. What is the lost update?
  2. A HashMap of tickets: if (!map.containsKey(id)) map.put(id, ticket). Name the two steps. What collection operation closes the gap?
  3. You locked issueTicket(). Two cars still share 101. Which object did you fail to name as shared state?

Read next

Takeaway

A race is two gates, one fact, check-then-act. Walk the interleaving. Name occupancy. Then pick CAS, a lock, or confinement. The keyword is not the story.