Locks & Compare-and-Swap (CAS)

Two fundamental approaches to preventing race conditions in concurrent systems.

🔐 Two Approaches to Thread Safety

When multiple threads need to modify shared data, we need mechanisms to prevent corruption.  Locks use blocking—threads wait in line.  CAS is non-blocking—threads retry until they succeed.

🔒 Locks (Mutexes)

  • ✓ Simple mental model
  • ✓ Works for complex critical sections
  • ✗ Can cause deadlock if misused
  • ✗ Blocking reduces throughput

⚡ CAS (Lock-Free)

  • ✓ No blocking—always making progress
  • ✓ Better performance under contention
  • ✗ Only works for simple operations
  • ✗ May retry many times (spinning)

🎬 What to Watch

In the Lock demo, watch threads queue up and enter one at a time. In the CAS demo, see how threads can fail and retry when their expected value doesn't match.

Locks / MutexesBlocking

Mutual Exclusion

Only one thread can hold the lock at any time, preventing simultaneous access.

Wait in Queue

Other threads block and wait until the lock becomes available.

Trade-off

Simple but can cause contention and potential deadlocks if misused.

Critical Section

Available

Waiting Queue

Click start to see threads queue up

Compare-And-Swap (CAS)Lock-Free

Optimistic

Assume no conflict, read value, compute new value, then attempt swap.

Atomic Check

Hardware ensures compare and swap happen as one uninterruptible operation.

Retry on Fail

If value changed, re-read and retry. No blocking, just spin.

Shared Memory

counter =
100
// CAS Operation
do {
old = read(counter)
new = old + 1
} while (!CAS(counter, old, new))

CAS Attempts Timeline

Click start to see multiple threads competing with CAS

When to Use Each Approach?

Use Locks When

  • • Critical section has complex operations
  • • Low contention expected
  • • Simplicity is prioritized

Use CAS When

  • • Operations are simple (counters, flags)
  • • High contention expected
  • • Maximum throughput needed