Concurrency
This domain tests thread creation, the Java memory model, safe coordination and the concurrency utilities.
Creating tasks
Thread takes a Runnable; start() launches a new thread while calling run() directly executes on the caller. Callable returns a value and may throw checked exceptions; submit it to an ExecutorService and get a Future whose get() blocks and throws ExecutionException wrapping the task's failure. Thread states are NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING and TERMINATED. Use shutdown() for graceful termination and shutdownNow() to interrupt.
Visibility and atomicity
volatile guarantees visibility and prevents reordering but not atomicity: volatile int count; count++; still loses updates. Use synchronized or AtomicInteger. synchronized also establishes happens-before, so writes before a monitor exit are visible after the matching acquire. Immutable objects with final fields are safely publishable.
wait/notify
wait, notify and notifyAll require holding the object's monitor, otherwise IllegalMonitorStateException. Always wait inside a loop that rechecks the condition because of spurious wakeups.
Concurrent collections
ConcurrentHashMap rejects null keys and values but offers atomic computeIfAbsent, merge and putIfAbsent; its iterators are weakly consistent and never throw ConcurrentModificationException. CopyOnWriteArrayList suits read-mostly lists. BlockingQueue implementations coordinate producers and consumers. CompletableFuture composes async stages with thenApply, thenCompose and exceptionally.
Worked example
Two threads incrementing a shared volatile int a million times each commonly produce a total below two million. Reasoning: ++ is read-modify-write, and volatile does not make the compound operation atomic, so interleaved updates are lost.
Traps
Calling run() instead of start(); assuming volatile is enough for counters; acquiring two locks in opposite orders in different threads, which deadlocks; forgetting to shut down an executor so the JVM keeps running.