04 · Java language in depth / LESSON 17 OF 102
JVM memory, thread safety, and virtual threads
A request may share objects with many other requests; thread safety is a property of that shared behavior.
Before this lesson: Annotations and reflection before Spring
Understand the topic
Each thread has its own stack frames, while objects can be shared on the heap. AtomicInteger supports atomic counter updates; volatile visibility alone does not make count++ atomic. Keep request-specific state out of singleton service fields.
Java 21 virtual threads make blocking workloads easier to scale in terms of threads, but they do not increase database capacity or make CPU work faster. Bound access to scarce resources. Use thread dumps to inspect blocked work and heap evidence before guessing about leaks.
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 {
var count = new AtomicInteger();
try (var pool = Executors.newVirtualThreadPerTaskExecutor()) {
var a = pool.submit(count::incrementAndGet);
var b = pool.submit(count::incrementAndGet);
a.get(); b.get();
}
System.out.println(count.get());
}
}What to expect
Prints 2 after both tasks finish; exceptions are observed through Future.get.
YOUR TURN
Put it into practice
- 01Compare a shared unsafe counter with AtomicInteger.
- 02Repeat parallel updates and capture a thread dump while deliberately blocking one worker.
- 03Verify: The safe counter preserves every update and you can identify a waiting thread from its stack.
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
A request may share objects with many other requests; thread safety is a property of that shared behavior.
- 01Each thread has its own stack frames, while objects can be shared on the heap. AtomicInteger supports atomic counter updates; volatile visibility alone does not make count++ atomic. Keep request-specific state out of singleton service fields.
- 02Java 21 virtual threads make blocking workloads easier to scale in terms of threads, but they do not increase database capacity or make CPU work faster. Bound access to scarce resources. Use thread dumps to inspect blocked work and heap evidence before guessing about leaks.
- 03Trace the example: Prints 2 after both tasks finish; exceptions are observed through Future.get.
A mistake worth avoiding
Increasing thread count makes database requests slower.
DEBUGGING ROOM
Something broke. Where do you look?
Increasing thread count makes database requests slower.
Before revealing the diagnosis, write down your first investigation step.
CHECK YOUR UNDERSTANDING
Do virtual threads make a CPU-bound loop intrinsically faster?
BUILD IT YOURSELF
Compare a shared unsafe counter with AtomicInteger.
- 1.Compare a shared unsafe counter with AtomicInteger.
- 2.Repeat parallel updates and capture a thread dump while deliberately blocking one worker.
- 3.Reproduce this failure, then repair it: Increasing thread count makes database requests slower.
Acceptance checklist
Lab completion is your self-report. Knowledge checks do not certify project quality.
RETRIEVE IT FROM MEMORY
Do virtual threads make a CPU-bound loop intrinsically faster?
Revisit this lesson in three days after a successful check or lab.
Ready for the next step?
The safe counter preserves every update and you can identify a waiting thread from its stack.
Reading is separate from passing a knowledge check or completing a lab.