Java Multithreading and High Concurrency Basics (5) - Java Memory Model

In the specification of the virtual machine, the Java Memory Model (JMM) is defined to shield the differences between various hardware and operating system memory accesses. After the release of JDK1.5 (which implements JSR-133), the Java memory model has been gradually improved.

 

1. Key problems to be solved by concurrent programming

We know that JMM is built around how to deal with the three characteristics of atomicity, visibility, and ordering in the concurrent process.

1. Atomicity: Please refer to http://zhaodengfeng1989.iteye.com/blog/2418779 for atomicity

2. Visibility: that is, the mechanism by which information exchanges between threads (also called thread communication). In imperative programming, there are two ways of communication between threads: shared memory and message passing.

Shared memory : In the concurrency model of shared memory, shared variables of memory are shared between threads, and implicit communication between threads is performed by writing-reading shared variables in memory between threads .

②Message passing : In the concurrency model of message passing, there is no public state between threads, and explicit communication is performed by explicitly sending messages .

3. Orderliness: also known as thread synchronization, refers to the mechanism used in the program to control the relative order of operations between threads.

① In the shared memory concurrency model, it is necessary to explicitly specify that a certain piece of code in the program needs to be executed mutually exclusively, so the synchronization between threads is performed explicitly.

② In the concurrency model of message passing, synchronization between threads is performed implicitly due to the relative order in which messages are sent and received .

 

Java's concurrency model uses shared memory . Java threads communicate implicitly through shared memory, which is completely transparent to the outside world. That is, we see the Java memory model today.

 

2. The structure of the Java memory model (also called abstract structure)

1. How to communicate between threads

In the architecture of the virtual machine, we know that the heap memory and method area are shared by all threads. Therefore, the shared memory model we call is also based on these two areas. Therefore, shared variables are variables defined in shared memory, including object instances, static fields, and array elements.

Let's take a look at the abstract structure diagram of JMM:


 From the abstracted JMM structure, JMM defines the relationship between threads and the main memory (shared memory). Each thread has a private local memory (Local Memory), and a copy of the shared variable is stored in the local memory. Of course, the thread's local memory is a concept abstracted in JMM, which covers the processor's cache, read and write buffers, registers, a part of hardware and compiler optimizations.

 

According to the abstract structure of JMM, let's talk about how threads communicate under the concurrency model of shared memory.

According to the above figure, we can know that to communicate between threads A and B, two steps must be performed.

First, thread A refreshes the updated copy of the shared variable in the local memory to the main memory;

The second is that thread B reads the shared variable updated by thread A from main memory.

 

Let us illustrate with an example. Suppose there are now two threads, thread A and thread B, and the shared variable x is cached in the local memory of thread A and B, and x is the initial state value of 0.

When thread A updates the shared variable x=1, according to the abstract structure of JMM, we know that threads A and B need to communicate, so the first step is to write the updated x into the main memory, then At this point, x=1 in main memory. Then the second step thread B reads the updated variable x=1 in the main memory and caches it in the local cache of thread B, then at this time, the shared variable x in thread B is also 1 (see the post http for the mechanism involved here ://zhaodengfeng1989.iteye.com/blog/2418346 ). The process is shown in the figure below.

 


 As can be seen from the above, JMM communicates between threads by controlling the interaction of main memory (shared memory) and thread-local memory.

 

2. How does thread execution perform sequential operations?

From the Java source code to the final sequence of instructions actually executed on the processor, there are 3 kinds of reordering.


① Compiler optimization reordering: The execution order of statements can be rearranged without changing the single-threaded serial semantics.

②Instruction-level parallel reordering: Modern processors use instruction-level parallelism (ILP, Instruction-Level-Parallelism) to overlap and execute multiple instructions. If there is no data dependency, the processor can change the execution of the corresponding machine instruction of the statement order to form an instruction pipeline .

③ Reordering of the memory system: Since the processor uses caches and write buffers, load (read) and store (write) operations appear to be performed out of order.

The above ① belongs to the compiler reordering, and ②③ belongs to the processor reordering.

What we must remember is that,

For compilers , the JMM's compiler reordering rules prohibit certain types of compiler reordering .

For processor reordering , JMM's processor reordering rules require that a specific type of memory barrier instruction (Memory Barrier/Fence) be inserted when the Java compiler generates an instruction sequence, and a specific type of processor reordering is prohibited by a specific memory barrier instruction . .

 

In the next post, we will focus on reordering and Happen-before principles. They are the key to understanding JMM! !

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326038756&siteId=291194637