Part 6 · Fundamentals

Concurrency, visibility and virtual threads

Prerequisites: 01-ecosystem

Where should concurrency be limited?

Many tasks: virtual threads; Semaphore: bounded admission; DB / insurer: scarce capacity; Waiting tasks: do not consume slots. Connections: Many tasks to Semaphore (request slot); Semaphore to DB / insurer (admitted work); Semaphore to Waiting tasks (no slot available)
Limit the scarce downstream resource. The figure illustrates admission control, not virtual-thread scheduling internals. [S11] [S12] [S13]

Goal & mental model verified

Concurrency coordinates overlapping tasks. Visibility and atomicity are different: volatile can publish writes, but does not make read-modify-write increments atomic. Virtual threads make blocking I/O concurrency cheaper; they do not create CPU or database capacity.

[S11] [S12]

Worked example · design exercise synthesis

Two workers read count=0 and both write 1: one increment is lost. AtomicInteger or a lock can protect this invariant. For quote calls, a semaphore can bound access to a scarce insurer connection.

[S11] [S12] [S13]

Engineering decision synthesis

Use virtual threads for many blocking I/O tasks when dependencies fit. Bound downstream concurrency; use workload-appropriate executors for CPU work and decide timeout/cancellation ownership.

[S11] [S12] [S13]

Pitfall & diagnosis synthesis

A shared mutable singleton remains shared under virtual threads. Avoid pooling virtual threads. Pinning guidance is JDK-dependent; older synchronized pinning advice should not be repeated universally for newer JDKs.

[S11] [S12] [S13]

Improve & validate synthesis

Load-test with slow dependencies. Record pool wait, in-flight calls, CPU and tail latency; stop increasing concurrency when the constrained resource saturates.

[S11] [S12] [S13]
Keep this: Cheap waiting is not unlimited throughput.
Check yourself: Does volatile count++ become atomic?

No. Reading, adding and writing remain a compound operation.

Sources & further reading

  1. [S11] Concurrency utilities

    Oracle / OpenJDK · documentation · accessed 2026-10-09 · Java SE 25

    Supports: Executors and concurrency building blocks

    Read the linked section to validate the mechanism and its version-specific constraints.

  2. [S12] JLS: threads and locks

    Oracle / OpenJDK · specification · accessed 2026-10-09 · Java SE 25

    Supports: Happens-before; Visibility versus compound atomicity

    Read the linked section to validate the mechanism and its version-specific constraints.

  3. [S13] Virtual threads

    Oracle / OpenJDK · documentation · accessed 2026-10-09 · Java SE 25

    Supports: I/O concurrency; Do not pool virtual threads; Limit scarce resources

    Read the linked section to validate the mechanism and its version-specific constraints.