Java SE 11 Developer study materials
Java SE 11 Developer study resources

Java SE 11 Developer: Concurrency

Java SE 11 Developer · Work through your exam, one topic at a time.

All guide sections

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.