Are java primitive ints atomic by design or by accident?

All memory accesses in Java are atomic by default, with the exception of long and double (which may be atomic, but don’t have to be). It’s not put very clearly to be honest, but I believe that’s the implication.

From section 17.4.3 of the JLS:

Within a sequentially consistent
execution, there is a total order over
all individual actions (such as reads
and writes) which is consistent with
the order of the program, and each
individual action is atomic and is
immediately visible to every thread.

and then in 17.7:

Some implementations may find it
convenient to divide a single write
action on a 64-bit long or double
value into two write actions on
adjacent 32 bit values. For
efficiency’s sake, this behavior is
implementation specific; Java virtual
machines are free to perform writes to
long and double values atomically or
in two parts.

Note that atomicity is very different to volatility though.

When one thread updates an integer to 5, it’s guaranteed that another thread won’t see 1 or 4 or any other in-between state, but without any explicit volatility or locking, the other thread could see 0 forever.

With regard to working hard to get atomic access to bytes, you’re right: the VM may well have to try hard… but it does have to. From section 17.6 of the spec:

Some processors do not provide the
ability to write to a single byte. It
would be illegal to implement byte
array updates on such a processor by
simply reading an entire word,
updating the appropriate byte, and
then writing the entire word back to
memory. This problem is sometimes
known as word tearing, and on
processors that cannot easily update a
single byte in isolation some other
approach will be required.

In other words, it’s up to the JVM to get it right.

Leave a Comment