Visibility is different from atomicity
The Java memory model defines when writes become visible and the ordering guarantees of synchronization actions. A volatile field supports visibility and ordering for that field, but count++ still performs a read, arithmetic and write. synchronized protects a critical section; AtomicInteger exposes specific atomic actions. If a rule spans several fields or objects, individually atomic field updates may not preserve that rule.
Shared collections and overload
ConcurrentHashMap provides defined concurrent access and atomic per-key operations such as merge, but its mutable values and cross-key sequences need their own coordination. Executors also require a capacity and lifecycle policy. An unbounded backlog can hide overload until memory or latency collapses. Bound scarce resources, distinguish queue wait from execution time and propagate deadline/cancellation decisions deliberately.
Threads are not extra downstream capacity
Virtual threads are well suited to large numbers of waiting tasks, not faster CPU arithmetic. They do not increase a database pool size or a vendor quota. Version matters: JDK 24 removed the earlier monitor-related pinning limitation; native or foreign operations can still pin. CompletableFuture expresses composition, but blocking join calls and an unsuitable executor can erase its benefit. Measure the real workload before changing execution models.
Worked Java example
Illustrative snippet: imports, surrounding types or collaborators may be omitted. Read the assumptions before adapting it.
ConcurrentHashMap<String, Integer> counters = new ConcurrentHashMap<>();
void record(String route) {
counters.merge(route, 1, Integer::sum);
}Walkthrough
merge makes the update for one route atomic under concurrent callers. A get-then-put alternative can lose an increment if both callers read the old value. This design still needs a bounded set of route names: using raw user IDs or full URLs can grow the map indefinitely. Per-key atomicity does not provide a consistent snapshot across every route.
Practice it yourself
Design a bounded worker service. State what happens when the queue is full, a task exceeds its deadline and shutdown begins.
Check your reasoning
Choose a bounded queue and explicit rejection/backpressure policy, account for queue time in the deadline, make interruption/cancellation cooperative where possible, and stop admission before draining or cancelling work during shutdown. Do not promise cancellation of a remote operation that may already have committed.
Recall checklist
- Explain the main invariant or contract without looking.
- Trace the example and test an edge case.
- State time, space, input variables and assumptions where relevant.
- Explain one alternative and when you would choose it.