03 · Practical Java / LESSON 9 OF 102
Threads and shared state
Web servers process multiple requests concurrently.
Before this lesson: Records, lambdas, and streams
Understand the topic
An executor runs tasks; Futures represent results. AtomicInteger provides atomic increments. volatile provides visibility but does not make read-modify-write operations atomic.
Virtual threads suit many blocking operations; they do not create more CPU cores. Keep request-specific data out of singleton fields. Thread safety and database transactions address different problems.
EXAMPLE · JAVA
Main.java
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
public static void main(String[] args) throws Exception {
AtomicInteger count = new AtomicInteger();
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
Future<?> first = executor.submit(() -> count.incrementAndGet());
Future<?> second = executor.submit(() -> count.incrementAndGet());
first.get(); second.get();
}
System.out.println(count.get());
}
}What to expect
2 on Java 21.
YOUR TURN
Put it into practice
- 01Explain what Future.get waits for.
- 02Describe the race with a plain shared counter.
- 03Identify which web-request state should be local.
Pass a quiz or complete a lab to check today’s streak. Each lesson counts once per day, including when you review it later.
UNDER THE HOOD
Build the mental model
Correct concurrent code requires reasoning about operations that may overlap, not just lines that look separate.
- 01count++ performs a read, calculation, and write. Two threads may both read the same old value and lose an increment.
- 02An atomic operation protects that operation, not an entire multi-step business rule. Checking balance then subtracting is still a larger critical section.
- 03Virtual threads reduce the cost of waiting on supported blocking work. Bound downstream resources such as database connections even with many virtual threads.
A mistake worth avoiding
A thread-safe collection does not automatically make a check-then-act sequence safe.
DEBUGGING ROOM
Something broke. Where do you look?
Occasional duplicate IDs appear under load.
Before revealing the diagnosis, write down your first investigation step.
CHECK YOUR UNDERSTANDING
Does volatile make counter++ atomic?
BUILD IT YOURSELF
Demonstrate a race and fix it
- 1.Run many concurrent increments.
- 2.Compare an unsafe shared counter with AtomicInteger.
- 3.Explain why a stress test passing once does not prove thread safety.
Acceptance checklist
Lab completion is your self-report. Knowledge checks do not certify project quality.
RETRIEVE IT FROM MEMORY
Which operation must be atomic in your actual business rule?
Revisit this lesson in three days after a successful check or lab.
Ready for the next step?
Distinguish concurrency, parallelism, visibility, and atomicity.
Reading is separate from passing a knowledge check or completing a lab.