A concurrency answer must separate visibility, atomicity, ordering, and task lifetime because no single keyword supplies every guarantee.
Java concurrency interview questions: visibility and atomic updates
Java 8+. Use a JDK that supports this release.
Does volatile make increment atomic?
No. A volatile field supplies visibility and ordering rules for its reads and writes, but count++ is a read-modify-write sequence. Two threads can compute the same next value and lose an increment.
A lock can protect a group of related updates. An atomic counter can protect one counter operation. Choosing the smaller tool requires a proof that the invariant really involves only that one value.
What does thread-safe collection mean for compound work?
Two individually safe calls do not automatically form one atomic operation. Checking a mapping and then putting a value can race with another writer. Use an operation whose contract covers the needed update, or protect the whole sequence.
If a collection returns a mutable value, thread-safe storage of its reference does not make arbitrary mutations of that value safe. Ownership still matters.
Does a successful submit mean the task succeeded?
No. Submission admits or rejects work. Future.get observes completion or reports failure. A discarded Future can conceal a task exception from the caller’s normal control flow.
Shutdown stops admission under the executor’s contract, but cancellation and interruption are cooperative. A task that ignores interruption can outlive the caller’s desired deadline. Executor ownership covers the complete lifecycle.
Do virtual threads remove backpressure?
No. They change how threads are represented and scheduled, not the capacity of a downstream database or the amount of pending state the application can retain. A producer still needs an admission policy.
The probe uses two platform threads and an atomic counter. join waits for their completion before the final read. This deterministic result is a correctness check for these updates, not a contention benchmark.
Working program
import java.util.concurrent.atomic.AtomicInteger;
public class CounterInterviewProbe {
public static void main(String[] args) throws InterruptedException {
AtomicInteger accepted = new AtomicInteger();
Runnable worker = () -> {
for (int receipt = 0; receipt < 1000; receipt++) accepted.incrementAndGet();
};
Thread first = new Thread(worker); Thread second = new Thread(worker);
first.start(); second.start(); first.join(); second.join();
System.out.println(accepted.get());
}
}Output
2000Cost and design choices
There are 2000 atomic updates. Contention and scheduling determine their elapsed time; the small fixed run cannot rank alternative counter implementations.
Integer counters can still overflow. Atomicity prevents lost updates, not range errors or incorrect business accounting.
Common Mistakes
- Do not propose volatile alone for a compound counter update.
- Do not discard task failures.
- Do not treat interruption as forced termination.
Connect the contracts
Compare the boundary explained in Visibility and atomicity with the assumptions made by this program.
