# Java's Atomic and volatile, under the hood on x86

DevFeed: [Java's Atomic and volatile, under the hood on x86](<https://devfeed.tech/articles/java-s-atomic-and-volatile-under-the-hood-on-x86-12445.md>)

Original publisher: [Read original article](<http://brooker.co.za/blog/2012/11/13/increment.html>)

Author: Marc Brooker

Published: 2012-11-13T00:00:00Z

Content type: tutorial

Language: en

Sources: [Marc Brooker's Blog](<https://devfeed.tech/sources/marc-brooker-s-blog.md>), [Marc Brooker's Blog](<https://devfeed.tech/sources/marc-brooker-s-blog-2.md>)

Topics: [Code](<https://devfeed.tech/topics/code.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Concurrent Programming](<https://devfeed.tech/topics/concurrent-programming.md>), [cpu](<https://devfeed.tech/topics/cpu.md>)

Tags: [atomic](<https://devfeed.tech/tags/atomic.md>), [code](<https://devfeed.tech/tags/code.md>), [cpu](<https://devfeed.tech/tags/cpu.md>), [java](<https://devfeed.tech/tags/java.md>), [loops](<https://devfeed.tech/tags/loops.md>), [memory](<https://devfeed.tech/tags/memory.md>), [processors](<https://devfeed.tech/tags/processors.md>), [program](<https://devfeed.tech/tags/program.md>), [servers](<https://devfeed.tech/tags/servers.md>), [thread](<https://devfeed.tech/tags/thread.md>), [x86](<https://devfeed.tech/tags/x86.md>)

## AI overview

This article explains why Java volatile variables provide visibility but not atomicity, using a multithreaded counter as an example. It compares non-volatile, volatile, and AtomicInteger implementations on x86 hardware, showing their correctness and performance differences.

## Source excerpt

Java's Atomic and volatile, under the hood on x86 How exactly do AtomicInteger and volatile do their magic in Java? It's well known that volatile in Java doesn't mean the same thing as atomic. As Jeremy Manson says: If you do an increment of a volatile integer, you are actually performing three separate operations: 1) Read the integer to a local. 2) Increment the local 3) Write the integer back out to the volatile field. On the other hand, the Java memory model is known to offer looser guarantees than some real hardware implementations. Most modern desktops (and most current servers) are powered by x86-family processors, which have fairly predictable memory behavior, especially compared to some other processor families. Despite these stronger guarantees, volatile int doesn't behave like AtomicInteger, even on x86 and even for a very simple operation like counting. Why not? To understand what is going on under the hood, let's start with a very simple piece of code, which does only three things: Launches M threads Loops a large number of times (N) in each thread, incrementing a shared variable. Joins the threads. The three threads are running in parallel, and sharing the value of the variable. For it to end up with the right value at the end (M*N), two things need to be true. First, changes made by one threads must be immediately visible to the other threads. Second, changes made to the variable must be atomic - each threads must perform the load, increment and save as one effective operation. Visibility is not enough, because it allows something like this to happen: Thread 1 loads 5 Thread 1 increments its private copy to 6. Thread 2 stores 6 Thread 1 stores 6 Even if changes are immediately visible, increments done by done by one thread can be lost by others. To see the effects of this, we can start with a version of the program with a non-volatile shared variable, which offers neither visibility nor atomicity. On my system, based on a four-core Intel Core2 Q6600 CP