Fundamentals 9 min read

Is Java’s long Truly Atomic? Exploring JVM Memory Model Behavior

This article investigates whether long and double variables are atomic in the JVM, demonstrates non‑atomic behavior on 32‑bit HotSpot with a multithreaded test, explains the Java Memory Model rules, and shows that atomicity is guaranteed on 64‑bit JVMs or when using volatile.

Programmer DD
Programmer DD
Programmer DD
Is Java’s long Truly Atomic? Exploring JVM Memory Model Behavior

Is the operation on long in the JVM atomic?

First, a program is used to test the atomicity of long. The test code is shown below:

public class LongAtomTest implements Runnable {
    private static long field = 0;
    private volatile long value;
    public long getValue() { return value; }
    public void setValue(long value) { this.value = value; }
    public LongAtomTest(long value) { this.setValue(value); }
    @Override
    public void run() {
        int i = 0;
        while (i < 100000) {
            LongAtomTest.field = this.getValue();
            i++;
            long temp = LongAtomTest.field;
            if (temp != 1L && temp != -1L) {
                System.out.println("出现错误结果" + temp);
                System.exit(0);
            }
        }
        System.out.println("运行正确");
    }
    public static void main(String[] args) throws InterruptedException {
        String arch = System.getProperty("sun.arch.data.model");
        System.out.println(arch + "-bit");
        LongAtomTest t1 = new LongAtomTest(1);
        LongAtomTest t2 = new LongAtomTest(-1);
        Thread T1 = new Thread(t1);
        Thread T2 = new Thread(t2);
        T1.start();
        T2.start();
        T1.join();
        T2.join();
    }
}

The program creates two threads (t1 and t2). Each thread repeatedly writes the static field with 1 or -1, then reads it back. If the read value is neither 1 nor -1, the program prints the unexpected value and exits.

When the write and read of long are atomic, the field can only be 1 or -1.

Running the program on a 32‑bit JVM produces output such as:

32-bit
出现错误结果-4294967295
运行正确

This shows that when both threads write to long simultaneously, a value that is neither 1 nor -1 can appear, indicating that the JVM does not treat long operations as atomic on 32‑bit platforms.

Why isn’t the operation on long atomic?

The JVM memory model defines eight atomic actions: lock, unlock, read, load, use, assign, store, and write. The actions related to reading and writing a variable are read, load, use, assign, store, and write.

According to the Java Language Specification (JLS), a non‑volatile 64‑bit long or

double> is treated as two separate 32‑bit writes, which can lead to a thread seeing the high half from one write and the low half from another.</p>
<blockquote>
<ul>
<li>Writes and reads of volatile <code>long

and double values are always atomic. Writes and reads of references are always atomic, regardless of size. Implementations may split a 64‑bit write into two 32‑bit writes for efficiency, but they are free to perform the operation atomically. JVM implementations are encouraged to avoid splitting 64‑bit values and programmers should declare shared 64‑bit values as volatile or synchronize correctly. Summarizing the specification:

On a 64‑bit JVM, a non‑volatile long or double may be written in two 32‑bit steps.

Marking the variable as volatile makes reads and writes atomic.

Reference reads/writes are always atomic.

The JVM is free to choose whether to implement 64‑bit reads/writes atomically.

It is recommended that JVMs implement them atomically.

Experimental results show that HotSpot on a 32‑bit system does not make long reads/writes atomic; it splits the operation into two 32‑bit actions.

What about a fully 64‑bit hardware, OS, and JVM?

On a 64‑bit environment, a single instruction can handle 64‑bit data, so reading or writing a long or double can be performed atomically. Running the same test on a 64‑bit JVM repeatedly yields only correct results:

64-bit
运行正确
运行正确

Thus, on a 64‑bit JVM the handling of long is atomic.

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.

JavaJVMconcurrencyMemory Modelatomicity
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

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.