Java Memory Model, Java Memory Model, I personally prefer the translation of Java Memory Model.

introduce

As mentioned earlier, the JVM was designed to be an abstract virtual machine, and the concurrency problems and solutions for the JVM have a lot in common with the concurrency problems in physical computers.

Due to the huge difference between memory and CPU speed in modern computers, it is common to add a layer of Cache, which is closer to the CPU read/write speed. The data used in an operation is copied to the Cache to speed up the operation, and then synchronized from the Cache back to memory. This design resolves the contradiction of speed, but it also introduces a new problem: cache consistency. In a multi-CPU system, each CPU has its own Cache and they share the same main memory. When multiple cpus perform computing tasks in the same memory area, data in their caches may be inconsistent. A Cache consistency protocol, such as MESI, is designed to ensure that each CPU follows these protocols when reading or writing Cache data. The Memory Model abstracts a specific cache read/write access process under a specific protocol. Physical machines with different architectures have different memory models, and Java virtual machines have their own memory models, the underlying principles of which are common.

In addition, in order to make full use of the CPU’s operation unit, the input code may be optimized for out-of-order execution, only to ensure the consistency of execution results, but not to ensure that the calculation order of each statement is consistent with the input code. The Just-in-time compiler for the Java virtual machine has a similar optimization for instruction reordering.

The Java language specification attempts to define a Java memory model to achieve consistent memory access effect for Java programs on various platforms, and to provide a set of effective balance between high throughput and consistency guarantee mechanism for multithreading synchronization and avoiding data contention.

What is the Java Memory model

A memory model describes whether a particular trace of a given program is a valid execution of that program. The Java memory model examines each read in the execution trajectory and verifies that the writes observed by that read are valid based on specific rules. The memory model describes the predictable behavior of a program, which is implemented with sufficient freedom to generate the required code, as long as its final execution results can be inferred from the memory model.

In layman’s terms, the Java Memory Model (JMM) defines a set of rules to ensure that writes from one thread are rendered correctly to other threads. The JMM does not describe how multithreading should perform, but rather what it allows.

The JMM specifies that all shared variables are stored in the MAIN memory of the JVM. Each thread has its own working memory, which is used to store the main memory copy of the variables used by the thread (the implementation usually does not copy the whole object). All operations on variables are carried out in the working memory by the thread, and variables in the main memory cannot be read or written directly. Different threads cannot directly access each other’s working memory, and the transfer of variable values between threads needs to be done through the main memory.

About the specific communication protocol between main memory and working memory, that is, a variable how to copy from main memory into the working memory, how to go from the working memory implementation details, such as synchronous back into main memory, JMM defines the eight kinds of operation (lock, unlock, read, load, the use, assign, store, write). The VM implementation must ensure that all the preceding operations are atomic and non-separable.

Shared variable/heap memory: Memory that can be shared between threads is called “shared or heap memory”. All instance fields, static fields, and array elements are stored in heap memory. Local variables in a method are never shared between threads and are not affected by the memory model. We also don’t need to worry about in-thread actions; each single thread should follow the correct in-thread semantics.

Inter-thread actions: Inter-thread actions are actions performed by one thread that can be detected or directly affected by another thread. Include:

Read/write of shared variables

Synchronization Action

The lock/unlock a monitor;

Read and write to a volatile variable

Start a thread

Actions that interact with the outside world

Thread devergence Action That causes a thread to enter an infinite loop

read

This article refers to in-depth Understanding of Java Virtual Machines and JSR-133-MemoryModel. If you have enough time, you can go through them completely, but the original text is more difficult to understand. This is a major clipping to hide a deeper layer of information for a quick but not overly superficial understanding of the Java memory model. More concepts and rules:

Cache consistency, Cache Coherence, MESI protocol

Instruction Reorder

Happens-before relationship rules

As-if-serial, meaning Serial within a thread

Memory barriers

References:

JSR-133 Java Memory Model

Java Language Specification SE8, chapter 17 threads and locks 17.4 Memory model

Chapter 12 in Understanding the Java Virtual Machine. The Java memory model and threads