Concurrency
Threads, synchronized, volatile and the Java Memory Model, locks, executors, CompletableFuture, concurrent collections, deadlocks and virtual threads.
A computer with eight cores can do eight things at the same moment, and a server spends most of its time waiting for databases and networks. Concurrency is how a Java program uses both facts: it runs several threads at once, so work finishes sooner and waiting doesn't block everything else. It is also the part of Java where the most expensive bugs live, because a program with a concurrency bug can pass every test and still fail once a week in production.
This phase builds the subject from the ground up. Topics 13.1 and 13.2 show what a thread is and how it moves through its life. Topic 13.3 shows the first big danger, the race condition, and the first tool, synchronized. Topic 13.4 explains the rules underneath everything, the Java Memory Model and its happens-before relation, and where volatile fits. Topic 13.5 covers explicit locks, conditions and wait/notify. Topics 13.6 to 13.8 move to the tools you use every day: executors, **CompletableFuture, concurrent collections and atomics. Topic 13.9 is about deadlock and its cousins. Topics 13.10 and 13.11 are modern Java: virtual threads (Java 21), structured concurrency (a preview feature) and scoped values** (final in Java 25).
Every runnable example prints the same output every time. Real thread timing is unpredictable, so the examples wait for threads with join, latches or futures before printing, and print totals and final states rather than the order in which threads happened to run. Where the point of a demo is that the result is unpredictable, the example says so and shows typical output instead. The DSA course's Concurrency-Aware Data Structures module (/dsa/concurrency-ds) puts these tools to work on interview problems such as Print in Order and the bounded blocking queue.