I interviewed with several companies last year, and almost every company asked about volatile, even in every interview round. Volatile is a popular question for interviewers because it can be used to refer to Java memory models, memory barriers, happen-befor, etc., which can be used to explore system instructions, hyper-threading, etc.

Java Memory Model (JMM)

Volatile is the lightest synchronization mechanism provided by the Java VIRTUAL machine, but it is difficult to understand and use properly. It may be helpful to understand volatile by studying the special access rules that the Java memory model defines for volatile.

The Java memory model defines the relationship between threads and memory: shared variables between threads are stored in main memory, and each thread has a private local memory that stores copies of shared variables to read/write. Local memory is an abstraction of the JMM and does not really exist; It covers memory, caches, registers, and other hardware and compiler optimizations. Java’s memory model is abstracted as follows:

Semantics of volatile

Volatile provides two main semantics:

1. Visibility:

Visibility is a value written by one thread that can be read immediately by other threads. As known from the Java memory model, each thread has local memory. So thread A writes something that under normal circumstances thread B cannot read immediately. However, with volatile variables, thread A is guaranteed to write directly to main memory without writing to local memory, and thread B is guaranteed to read directly from main memory without reading from local memory.

2, forbid instruction reordering:

Reordering is an optimization method by which compilers and processors reorder instructions to optimize program performance.

Several reorders of Java programs

Compiler optimization reordering: The compiler can rearrange the execution order of statements without changing the semantics of a single-threaded program. Instruction-level parallel reordering: If there is no data dependency, the processor can change the execution order of the machine instructions corresponding to the statement. Reordering of memory systems: Processors use caches and read and write buffers, which make it appear that load and store operations may be volatile out of order — memory barriers, the technical cornerstone of volatile operations

Memory barriers are CPU instructions that guarantee the ordering of certain operations and the visibility of certain memory. Inserting a barrier instruction tells the compiler and CPU that no instruction can be reordered with the barrier instruction. Another thing that memory barriers do is force various CPU caches to flush. A write-barrier, for example, will flush out all data written to the cache before the Barrier, so that any thread on the CPU can read the latest version of the data.

Java programs that generate assembly code for both volatile and non-volatile code will find that volatile code has an extra lock prefix.

Typical use cases for volatile

A code example for the status flag is as follows:

While thread 1 is executing run(), another thread 2 May have called shutdown, so the stop variable must be volatile (to take advantage of the visibility of volatile).

There is also a common use in the implementation of double-checked singletons with the following code:

Instance = new Singleton(), which is not an atomic operation, actually does three things in the JVM:

The Singleton constructor is called to initialize the member variable to point the instance object to the allocated memory. (After this step, instance is non-null.) Because of the reordering of instructions, the execution steps can be 1-2-3 or 1-3-2. Once it is 1-3-2, it may cause access to uninitialized memory. But with the volatile keyword, be sure to do it 1-2-3 (using volatile’s prohibition against reordering).

Welcome Java engineers who have worked for one to five years to join Java Architect: 697558955

Group provides free Java architecture learning materials (which have high availability, high concurrency, high performance and distributed, Jvm performance tuning, Spring source code, MyBatis, Netty, Redis, Kafka, Mysql, Zookeeper, Tomcat, Docker, Dubbo, multiple knowledge architecture data, such as the Nginx) reasonable use their every minute and second time to learn to improve yourself, don’t use “no time” to hide his ideas on the lazy! While young, hard to fight, to the future of their own account!