Mastering Thread Safety in Java: Atomicity, Visibility, and Ordering Explained

This article explains Java thread safety by defining it, breaking down atomicity, visibility, and ordering, illustrating core concepts with AtomicInteger and AtomicStampedReference examples, and detailing the underlying CAS mechanisms, JMM rules, and the ABA problem.

Java Interview Crash Guide
Java Interview Crash Guide
Java Interview Crash Guide
Mastering Thread Safety in Java: Atomicity, Visibility, and Ordering Explained

Definition

First, consider what thread safety means.

According to Java Concurrency in Practice , a class is thread‑safe if, regardless of scheduling or interleaving, it behaves correctly without requiring additional synchronization in client code.

Thread safety is analyzed through three aspects: Atomicity, Visibility, and Ordering.

Atomicity

Atomicity provides exclusive access so that only one thread can modify data at a time, e.g., using AtomicXXX classes or the synchronized keyword.

Visibility

Visibility ensures that a thread's modifications to main memory become promptly visible to other threads, e.g., via synchronized or volatile.

Ordering

Ordering guarantees that a thread observes other threads' instruction execution order; without it, instruction reordering can cause apparent disorder, addressed by the happens‑before principle.

Atomicity

AtomicXxx

The Java java.util.concurrent.atomic package offers many atomic classes such as AtomicInteger, AtomicLong, and AtomicBoolean.

Example with AtomicInteger:

class AtomicIntegerExample {
    private static final Logger log = LoggerFactory.getLogger(AtomicIntegerExample.class);
    // total requests
    public static int requestTotal = 500;
    // concurrent threads
    public static int threadTotal = 20;

    public static AtomicInteger count = new AtomicInteger(0);

    public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newCachedThreadPool();
        final Semaphore semaphore = new Semaphore(threadTotal);
        final CountDownLatch countDownLatch = new CountDownLatch(requestTotal);
        for (int i = 0; i < requestTotal; i++) {
            executorService.execute(() -> {
                try {
                    semaphore.acquire();
                    add();
                    semaphore.release();
                } catch (Exception e) {
                    log.error("exception", e);
                }
                countDownLatch.countDown();
            });
        }
        countDownLatch.await();
        executorService.shutdown();
        log.info("count:{}", count.get());
    }

    private static void add() {
        count.incrementAndGet();
    }
}

The key method is incrementAndGet():

/**
 * Atomically increments by one the current value.
 * @return the updated value
 */
public final int incrementAndGet() {
    return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}

This method implements an optimistic lock using a spin loop to update memory atomically via low‑level CPU instructions.

Spinning can be costly if it lasts long, consuming significant CPU resources.

AtomicStampedReference

To solve the ABA problem of CAS, Java provides AtomicStampedReference which pairs a value with a version stamp.

/**
 * Atomically sets the value of both the reference and stamp
 * to the given update values if the current reference is
 * == to the expected reference and the current stamp is
 * equal to the expected stamp.
 */
public boolean compareAndSet(V expectedReference,
                             V newReference,
                             int expectedStamp,
                             int newStamp) {
    Pair<V> current = pair;
    return expectedReference == current.reference &&
           expectedStamp == current.stamp &&
           ((newReference == current.reference &&
             newStamp == current.stamp) ||
            casPair(current, Pair.of(newReference, newStamp)));
}

This method checks both reference and stamp for equality before atomically updating them.

Visibility

What is thread‑to‑thread visibility? It means a thread’s change to a shared variable is promptly seen by other threads.

What is a shared variable? A variable that has copies in the working memory of multiple threads.

What is the Java Memory Model (JMM)? JMM defines the rules for accessing shared variables and how variables are stored in main memory and read into thread‑local working memory.

All variables reside in main memory.

Each thread has its own working memory holding copies of variables it uses.

Operations on shared variables must occur in a thread’s working memory; threads cannot directly access another thread’s working memory, and communication happens via main memory.

Ordering

Ordering means the execution order of program statements matches the written order.

Why can ordering be broken? — Reordering The JMM allows compilers and processors to reorder instructions, which does not affect single‑threaded correctness but can break multi‑threaded behavior.

Key happens‑before rules include program order, lock release/acquire, volatile write/read, transitivity, thread start, thread interrupt, thread termination, and object finalization.

Understanding visibility and ordering requires a solid grasp of the JMM; repeated study deepens comprehension.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Javaconcurrencyorderingthread safetyCASatomicityvisibility
Java Interview Crash Guide
Written by

Java Interview Crash Guide

Dedicated to sharing Java interview Q&A; follow and reply "java" to receive a free premium Java interview guide.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.