🧵

Java Concurrency & Multithreading

Threads, synchronization, the java.util.concurrent toolkit, and modern Java concurrency (virtual threads, structured concurrency) -- built from a race condition happening on purpose, not memorized API lists.

Practice interview questions on this topic →
1

Thread Basics & Lifecycle

beginner

What a thread actually is inside a running Java program, how it differs from a process, why concurrent execution exists at all, the six states a thread moves through, and why CPU caching means your code can misbehave even when the logic looks perfectly correct.

2

Creating Threads — Runnable vs Thread

beginner

Java offers four distinct ways to create and run a thread — subclassing Thread, implementing Runnable, using a lambda, and the modern Thread.Builder API — plus a fifth answer that supersedes all of them in real production code. This topic compares them, explains why some are discouraged, and covers the interrupt-handling mistake that trips up nearly every developer at least once.

3

Thread States, join(), sleep() & Daemon Threads

beginner

Creating a thread is the easy part — the harder skill is controlling one once it's running. This topic covers join(), sleep(), cooperative interruption, daemon threads, and uncaught exception handling: five small APIs that drive nearly all thread coordination, each with a sharp edge that trips up developers who only skim the method signature.

4

Synchronization & Intrinsic Locks

beginner

Nearly every threading bug traces back to one root cause: two threads touching the same mutable data at once, with no rule about who goes first. The synchronized keyword is Java's original built-in fix. This topic makes the bug happen on purpose, then builds the full toolkit for preventing it: method locks, block locks, class-level locks, reentrancy, and the visibility guarantee that comes bundled in for free.

5

wait(), notify() & notifyAll()

intermediate

synchronized answers how to stop two threads from touching the same data at once. It does not answer how one thread tells another that the thing it's waiting for just happened. wait()/notify() is Java's original inter-thread messaging system, and its exact rules are some of the most misunderstood -- and most interviewed -- details in the language.

6

ExecutorService & Thread Pools

intermediate

In real code you almost never create raw threads by hand -- you hand work to an ExecutorService and let it decide how many threads to use, when to create them, and how to shut down cleanly. This topic covers which pool type to reach for, how to configure one from scratch when the defaults are dangerous, how to size it, and how to shut it down without leaking threads or losing in-flight work.

7

Callable, Future & CompletionService

intermediate

How to submit a task that returns a real result and can fail with a checked exception, how to collect that result safely with Future, and how ExecutorCompletionService and fan-out/fan-in patterns handle many concurrent results without head-of-line blocking.

8

Explicit Locks: ReentrantLock, ReadWriteLock & StampedLock

intermediate

Move beyond the synchronized keyword to java.util.concurrent.locks -- lock objects that can time out, be interrupted, support multiple wait-conditions per lock, and let many readers proceed at once.

9

Atomic Variables & Compare-And-Swap

intermediate

Learn compare-and-swap, the single hardware instruction that lets threads coordinate without ever blocking, and how AtomicInteger, AtomicReference, LongAdder, and AtomicStampedReference build on it to handle counters, references, high-contention metrics, and the ABA problem.

10

BlockingQueue & the Producer-Consumer Pattern

intermediate

Use BlockingQueue to build producer-consumer pipelines with zero manual locking -- covering its four operation styles, its seven implementations, graceful shutdown with the poison pill pattern, and deliberate backpressure instead of unbounded growth.

11

Synchronizers: CountDownLatch, CyclicBarrier, Phaser & Semaphore

intermediate

Coordinate groups of threads with the four purpose-built synchronizers in java.util.concurrent -- waiting for N events, meeting all threads at a shared point, handling a variable number of participants across phases, and capping concurrent access to a limited resource.

12

Concurrent Collections: Thread-Safe Data Structures

intermediate

Replace HashMap, ArrayList, and Collections.synchronizedX with purpose-built concurrent collections -- ConcurrentHashMap's atomic compound operations, CopyOnWriteArrayList for read-heavy lists, ConcurrentSkipListMap for sorted access, and when a plain volatile field is actually enough.

13

CompletableFuture — Asynchronous Programming

advanced

Learn to chain, combine, and recover from failure on asynchronous computations without ever blocking a thread just to wait — the backbone of modern async Java.

14

ForkJoinPool & Parallel Streams

advanced

Understand the work-stealing scheduler behind divide-and-conquer parallelism, and learn exactly when parallel streams help versus when they quietly degrade a whole application.

15

ThreadLocal & Scoped Values

advanced

Give each thread its own private copy of a variable with ThreadLocal, understand its thread-pool failure mode, and see how Java 21's ScopedValue closes that gap structurally.

16

Virtual Threads — Project Loom

advanced

Learn how JVM-managed virtual threads let you write ordinary blocking code that scales to millions of concurrent tasks, and the thread-pinning pitfall that can silently erase their benefit.

17

Structured Concurrency

advanced

Treat a group of concurrent subtasks as one unit of work with a guaranteed beginning and end, with automatic cancellation propagation that a hand-assembled CompletableFuture chain has to wire up manually.

18

Concurrency Patterns & Best Practices

advanced

Recognize the recurring, named shapes -- worker pools, pipelines, bulkheads, circuit breakers -- that real systems assemble from concurrency primitives, and know which one a given problem actually needs.

19

Deadlocks, Livelocks & Starvation

intermediate

A deadlocked program doesn't crash - it just quietly stops, with no exception and no stack trace. this topic teaches you to diagnose and prevent deadlock from first principles, and to tell it apart from its two close cousins, livelock and starvation.

20

Performance Optimization: Latency, Throughput & Amdahl's Law

advanced

Latency and throughput are different metrics that often trade off against each other, and adding threads doesn't scale a program forever. this topic covers when to optimize for which metric, the hard ceiling Amdahl's Law puts on parallel speedup, and how to measure performance without being fooled by the JIT.

21

Lock-Free Data Structures & Algorithms

advanced

Lock-free programming eliminates blocking, deadlock risk, and priority inversion by using hardware compare-and-swap instructions instead of locks. this topic builds a lock-free stack, queue, and inventory counter from scratch on top of that one primitive.

22

I/O Threading Models: Blocking, Non-Blocking & Virtual

advanced

Every server framework makes a fundamental choice about how threads relate to I/O operations. this topic covers the three models - thread-per-request, async NIO, and virtual threads - and why they lead frameworks like Tomcat, Netty, and Spring Boot to such different designs.

23

Dining Philosophers Problem

intermediate

Five philosophers, five forks, and a rule that guarantees deadlock if nobody's careful. Dijkstra's 1965 thought experiment is the cleanest possible model of circular-wait deadlock, and this topic implements it, breaks it on purpose, and fixes it three genuinely different ways.

24

Advanced Topics: Exchanger, DelayQueue & Continuations

advanced

A grab-bag of the mechanisms that separate senior engineers from the rest: a two-party data handoff, time-based scheduling without a full scheduler, the memory model rules that make visibility guarantees precise, and the continuation mechanism that makes virtual threads possible.