What this course is about
Concurrency is the art of getting a computer to make progress on more than one thing at a time — and doing it correctly. It's one of the highest-leverage skills in software: it's what keeps a UI responsive while it loads data, lets a web server handle thousands of users at once, and allows a database to stay consistent while hundreds of transactions race against each other.
It is also, famously, where some of the hardest bugs in our profession live. A concurrent program can pass every test on your laptop and then corrupt data in production once a month, at 3 a.m., in a way you can never reproduce. This course is about understanding concurrency deeply enough that those bugs stop being mysteries and start being things you can reason about, prevent, and fix.
Think of a busy restaurant kitchen. One cook working alone is sequential — predictable, but slow. Add five cooks sharing the same counters, knives, and stove and you get concurrency: far more food per hour, but now you need rules. Who holds the one good knife? What happens when two cooks reach for the same pan? Most of this course is about those rules — and what goes wrong when a kitchen doesn't have them.
Who this course is for
This course is written for developers who are already comfortable writing ordinary, single-threaded programs and now want a rigorous, practical understanding of concurrency — whether to build high-throughput systems, to pass technical interviews, or to finally understand that flaky bug. You do not need any prior concurrency experience; we build every idea from the ground up.
You should be comfortable reading code and know basic data structures (lists, maps, queues). Java experience helps because our examples are in Java, but the concepts are universal — if you know any C-family or object-oriented language, you'll be able to follow along.
Concurrency is a set of portable mental models — races, mutual exclusion, visibility, deadlock — that show up in every language and runtime. We anchor them in Java so they're concrete, but what you learn transfers directly to Go, C#, Python, Rust, and beyond.
How the course progresses
The lessons follow a deliberate hierarchy: each idea unlocks the next. We start with how a single program runs, expose the problems that appear the moment two threads share memory, introduce the tools that fix those problems, and then climb toward modern, high-level models like virtual threads, async/await, and structured concurrency. Here's the shape of the journey:
Along the way, four capstone projects let you build the real thing: a thread-safe bounded buffer, your own thread pool, a concurrent web crawler on virtual threads, and a mini key-value store with both lock-based and lock-free variants.
How to use the Java examples
Every concept is paired with small, focused Java snippets. They're meant to be read first and run second — concurrency is one of the rare areas where running the same program twice can give different results, and seeing that with your own eyes is half the lesson. To follow along you'll want JDK 21 or newer, which includes virtual threads and the structured-concurrency APIs we use later.
public class HelloConcurrency {
public static void main(String[] args) throws InterruptedException {
Runnable greet = () -> System.out.println(
Thread.currentThread() + " says hello");
Thread a = new Thread(greet, "worker-A");
Thread b = new Thread(greet, "worker-B");
a.start(); // both run concurrently with main...
b.start();
a.join(); // ...and main waits for them to finish
b.join();
System.out.println("Done. Run me a few times — does the order change?");
}
}Run the program above several times. The order of the two "hello" lines may change between runs and you did nothing wrong — that non-determinism is the defining feature of concurrent code, and learning to tame it is what this whole course is about.
- Install JDK 21+, then compile and run a "Hello, World" to confirm your toolchain works (
java --versionshould report 21 or higher). - Run the
HelloConcurrencyprogram above five times and note whether the output order changes. Write down what you observe. - Sketch your own goals for this course in two or three sentences — what do you want to be able to build or understand by the end?
Do you need prior concurrency experience to take this course?
No. The course builds every concept from first principles. You only need comfort with single-threaded programming and basic data structures.
Why are the examples written in Java if the concepts are universal?
Java has a rich, mature concurrency toolkit that makes abstract ideas concrete and runnable. The mental models you build transfer to other languages — Java is the vehicle, not the destination.
Why does the course insist you run the examples, not just read them?
Because concurrent programs can behave differently on each run. Observing that non-determinism directly — different output orderings, occasional failures — is the fastest way to build real intuition.
- Concurrency means making correct progress on multiple things at once — powerful, but the source of our hardest bugs.
- The course goes from sequential execution all the way to real-world systems, one idea unlocking the next.
- It assumes no prior concurrency knowledge; examples are Java (JDK 21+) but the concepts are portable.
- Read the code, then run it — non-determinism is something you have to see to understand.