Concurrency & Parallelism Roadmap
From telling overlapping progress apart from simultaneous execution, through shared state, synchronization, deadlock and contention, to parallel decomposition, memory visibility and the judgement to decide that a system does not need any of it.
- 1
Concurrency, parallelism, tasks and threads
0 / 16 masteredSeparate "these things overlap" from "these things run at the same instant", and pick the unit of execution from the shape of the work rather than from habit.
What Concurrency Actually IsWhich One Does This Workload Need?Why Concurrency Exists: WaitingWhy Parallelism Exists: ComputeClassifying the Work: Computing or Waiting?Choosing an Execution ModelWhat "Making Progress" Actually MeansConcurrency Is Always Bought With ComplexityProcesses: Isolation You Cannot Accidentally BreakThreads: One Address Space, Several Instruction StreamsThread or Process?A Task Is Not a ThreadCoroutines: Functions That Can PausePython: Threads, Processes and the GILJavaScript: One Event Loop per Agent, Not One Thread per RuntimeC++: Threads, Atomics and a Memory Model With TeethOutcome · You can look at a piece of work, say whether it is waiting-bound or compute-bound, and name the execution model that follows — including the case where the answer is "run it sequentially".Prove it — The scheduler lab → - 2
Shared state, races and critical sections
0 / 15 masteredName the invariant before naming a primitive, and find the schedule that breaks it.
Shared Mutable StateInterleavings: The Schedule Is Part of the ProgramInvariants: Name It Before You Lock ItFinding the Critical SectionReasoning About Races: A Method, Not an InstinctData Race Is Not Race ConditionThe Atomicity IllusionNondeterminism: Same Input, Different OutputImmutability as a Concurrency StrategyCopy or Share?Copy-on-Write as a Concurrency StrategyOptimistic Concurrency ControlPessimistic ConcurrencyOptimistic vs PessimisticInitialization RacesOutcome · Given a function that two threads call, you can write down what must stay true, produce an interleaving that violates it, and say whether the fix is a lock or the removal of the sharing.Prove it — Break the counter → - 3
Mutexes, semaphores and condition variables
0 / 11 masteredChoose the primitive from the guarantee you need, and hold it over the smallest region that preserves the invariant.
Mutexes: What They Protect and What They Do NotLock Scope: What You Hold It AcrossRead/Write Locks, HonestlySemaphores: Counting Permits as a Resource LimitSemaphore versus Mutex: Not the Same PrimitiveCondition Variables: Waiting Until a Predicate Is TrueLost Wakeups: The Notify That Arrived Before the WaitSpurious Wakeups: Why It Is `while`, Not `if`Spin LocksWhat "Thread-Safe" Actually MeansReentrancyOutcome · You can say what a mutex guarantees and what it does not, why a condition variable is always waited on in a loop, and why "thread-safe" is a claim about a type's operations rather than a property you can sprinkle on.Prove it — Fix the counter → - 4
Async, promises, coroutines and event loops
0 / 16 masteredUnderstand what suspending a task actually does, what keeps running while it is suspended, and who owns a task once it is started.
Event Loops as a Concurrency ModelAwait Is a Yield PointFutures & PromisesWorker ThreadsWeb WorkersEvent Loop or Threads?Async Is Not ParallelismBlocking the Event LoopPromise.all & gatherThe Sequential Await TrapStructured ConcurrencyCancellationCancellation PropagationTimeoutsDeadlines vs TimeoutsOrphaned TasksOutcome · You can explain why anProve it — Stall the event loop →awaitin a loop is a latency bug and an unboundedPromise.allis a capacity bug, and why a task with no owner is the async equivalent of a leaked thread. - 5
Thread pools, worker pools, producer/consumer and backpressure
0 / 17 masteredTreat concurrency as a budget you set rather than a number that emerges, and decide what happens to the work that does not fit.
Producer / ConsumerBounded vs Unbounded QueuesBackpressureChannelsMessage PassingThe Actor ModelConcurrent QueuesDraining a PipelineThread PoolsSizing a Thread PoolWorker Pools Beyond ThreadsWork StealingPool SaturationBounding ConcurrencyUnbounded ConcurrencyThundering HerdSingle-Flight CoalescingOutcome · You can size a pool by reasoning rather than by folklore, and you can say exactly what a full queue should do — block, drop, or reject — and defend the choice.Prove it — Set a concurrency budget → - 6
Deadlocks, starvation, livelock and contention
0 / 15 masteredExplain how a system full of correct code stops making progress, and how to make the failure structurally impossible rather than unlikely.
DeadlockThe Four ConditionsPreventing DeadlockLock OrderingLivelockStarvationFairnessPriority InversionWhat Contention Actually CostsLock ConvoysFalse ParallelismOversubscriptionThe Cost of a Context SwitchMore Threads Is Not More SpeedBusy WaitingOutcome · You can draw a wait-for graph from a stack trace, name which of the four deadlock conditions your fix removes, and explain why the eight-core box was slower than the two-core one.Prove it — Deadlock lab → - 7
Atomics, memory ordering and lock-free
0 / 15 masteredLearn what an atomic operation actually makes indivisible, why another thread might not see your write at all, and why lock-free is a progress guarantee rather than a speed claim.
Atomics: What Is Actually IndivisibleCompare-and-Swap and the Retry LoopAtomics Are Not MagicLock-Free Is a Progress GuaranteeA Lock-Free Stack, and What the Teaching Version OmitsWait-Free vs Lock-Free: Whose Progress Is GuaranteedThe ABA Problem: The Value Came BackWhat a Memory Model DefinesHappens-Before: The Edge That Makes a Write VisibleReordering: The Compiler and the CPU Both Do ItMemory Barriers Constrain Ordering, Not CachesFalse Sharing: Different Variables, Same Cache LineWhat a Shared Write CostsSafe Publication: Handing Over a Finished ObjectDouble-Checked Locking: The Canonical Cautionary TaleOutcome · You can explain whyProve it — Watch a CAS loop retry →counter.fetch_add(1)is safe andif (!cache) cache = build()on an atomic pointer is not, and why the fix for double-checked locking is a memory-model question, not a syntax one. - 8
Parallel algorithms, fork/join and SIMD
0 / 18 masteredDecompose a computation into independent work, and predict the ceiling before writing any of it.
Fork/JoinParallel ReduceThe Map/Reduce PatternParallel AlgorithmsParallel OverheadAmdahl's LawGustafson's LawWork and SpanDependency GraphsSIMD: One Instruction, Many ElementsTask Parallelism vs Data ParallelismGPU Parallelism: Thousands of Lanes, One BusPipeline Parallelism: Different Items, Different StagesFan-Out / Fan-In: One Request Becomes NScatter/Gather and the Tail You InheritBarriersLatches & CountdownsParallelism Moves the Load DownstreamOutcome · You can compute the best speedup a decomposition can ever reach from its serial fraction and its span, and you know when the parallel version will lose to the sequential one.Prove it — Scaling lab → - 9
Parallel performance, debugging and production concurrency
0 / 31 masteredReceive "it is slow and occasionally wrong, and it only happens in production" and answer it with evidence instead of guesses.
Why Eight Cores Give You Four and a HalfMemory Bandwidth: More Cores, Same BusParallelism Can Destroy LocalityNUMA: Not All Memory Costs the SameThread Affinity: Pinning, and What It Costs YouReduction Ordering: The Sum Changed When the Worker Count DidDeterminism: Same Input, Same Output?Ordering Guarantees: Four Levels, Four PricesWhat to Instrument in a Concurrent SystemHold Time, Wait Time, and the Ratio Between ThemReading a Thread DumpTask Dumps: When the Threads Look Idle and Nothing Is MovingOff-CPU Time: The Thing a CPU Profiler Cannot SeeRace Detectors: What They Find, and What They Structurally CannotHeisenbugs: The Bug That Leaves When You Look at ItDeterministic Replay: Making the Schedule ReproducibleStress Testing: A Test That Passed Once Proves NothingChoosing a Concurrency Model for a ServerThread per Request: The Model That Reads Like Ordinary CodeEvent-Driven Servers: Many Connections, One LoopHybrid Runtimes: It Was Never Threads Versus AsyncUI Concurrency: One Thread Owns the ScreenThe Database Solves Concurrency For Its Data, Not For Your MemoryWhat Changes When the Shared State Is on Another MachineA Mutex on Server A Does Nothing About Server BThe Concurrency Pattern CatalogueConcurrency Anti-PatternsCan These Tool Calls Run At the Same Time?Parallel Tool Calls: Lower Latency, and Four BillsTwo Agents, One DocumentCancelling an Agent Run: What Actually StopsOutcome · You can instrument a concurrent system so the next failure leaves evidence, and you can design one whose concurrency model you are able to defend line by line — including the parts you chose to leave sequential.Prove it — Concurrency capstone →