JVM chapter of java memory model

In concurrent programming, we usually deal with two issues: how to communicate before the thread and how to synchronize between threads .

Communication refers to how the exchange of information between threads, the usual means of communication are: shared memory and message passing (different languages, different communication mechanisms, java using a shared memory concurrency model)

In concurrent shared memory model, the common state information sharing among threads by reading the state information of public - Write to implicitly performed so that a communication thread; in messaging concurrency model, since there is no direct information common thread state, the clear message is transmitted only to explicitly communicate

Refers to the relative order of the synchronization mechanism to control the operation of the different threads occurs, concurrent shared memory model, the explicit synchronization is performed, the programmer must explicitly specify a method or section of code you need to perform mutual exclusion between threads. In concurrency model's messaging, since the transmission message before receiving the message must therefore implicit synchronization is performed.

Due to the use of java concurrent shared memory model, communication between threads always done implicitly, the entire communication process is completely transparent to the programmer, if you do not understand the working mechanism of communication between threads implicitly carried out, it is likely to encounter to all sorts of strange memory visibility problems.

Abstract Java memory model

The above has given out Java concurrency model is the use of shared memory, a memory structure in the previous JVM, only two memory is shared between the threads, the heap and method area, so these two regions but also as a shared memory information storage area, including the instance fields, static fields and array elements (As used herein, "shared variable" refers to the generation of instance fields term, static fields and array elements)

Communications between threads is controlled by the Java Java memory model (herein referred to as JMM), JMM determine a thread writes to shared variables visible when another thread. From an abstract point of view, JMM defines an abstract relationship between the thread and the main memory: the threads share variables stored in main memory (main memory), each thread has a private local memory (localmemory), local memory stores a copy of the thread to read / write shared variables. JMM local memory is an abstract concept, and are not real. It covers the cache, write buffer, registers and other hardware and compiler optimizations. Abstract diagram of Java memory model are as follows:

Between threads A and B are as threads to be communicated, it must go through the following two steps (assuming the shared variable X):

1. A thread to update local memory X, and the updated shared variables in main memory to the brush.

2. Thread B into the main memory to read the thread A has been updated shared variable X, while updating the shared variable in the local memory (if the presence of the shared variable).

This communication process must go through the main memory. JMM by controlling the interaction between the main memory and the local memory of each thread, to provide visibility of memory guarantee java programmer.

Reordering

In order to improve performance when executing a program, the compiler and processor instructions would often be reordered. Reordering three types:

1. compiler optimization reordering. The compiler in single-threaded programs without changing the semantics of the premise, you can rearrange the order of execution of the statement.

2. ILP reordering. Modern processors employ instruction-level parallelism (Instruction-Level Parallelism, ILP) to overlap the plurality of instructions executed. If no data dependency exists, the processor may change the execution of machine instructions corresponding to the statement sequence.

3. reordering memory system. Since the processor uses the cache and the read / write buffer, which makes the load and store operations are executed may appear out of order.

Java from the final source code into a sequence of instructions actually executed, will undergo the following three reordering respectively:

1 above sorting compile-esteem, 2, and 3 are reordering processor. The reordering might result in a multithreaded program memory visibility problems. For the compiler to compile JMM's attention sorting rules prohibit a particular type of compiler thinks highly of the sort (not all compilers have discouraged the sort prohibited). For reordering processor, processor JMM reordering rules claim java compiler when generating a sequence of instructions, a particular type of memory barrier insert (memory barriers, intel called memory fence) instruction to disable a particular type of memory barrier instructions by reordering processor (not all processors must prohibit reordering).

Having said that, for example:

int a = 1; // step 1
boolean b = true; // step 2
复制代码

Under normal circumstances, it does not depend on the implementation of step1 step2, so now step1 step2 will reordering occurs. But if there is such a code behind:

if (b) {
    int c = a; //step 3
    System.out.println(c);
}
复制代码

A case is assumed in compiling discouraged sorting, thread 1, if performed prior to step2 step1, come Step3 thread 2, and the value of a step1 not yet flushed to main memory 1, and will not at this time the value of C 1, which is compiled esteem issues attracted the sort of front also talked about the processor reordering insert specific type of memory barrier, which is to solve the problems caused by the compiler thinks highly of the sort.

Memory barrier

Modern processors use the data written to the write buffer memory to temporarily save. Write buffer instruction pipeline can ensure continuous operation, it is possible to avoid the processor to a halt waiting for delayed write data to the memory generated. But the memory read / write operation execution order, not necessarily the actual memory read / write operations in the same order!

In order to ensure the visibility of memory, java compiler generated instruction sequence at an appropriate position of the inserted memory barrier instruction to disable a particular type of processor reordering. The memory barrier instruction JMM divided into the following four categories:

StoreLoad Barriers is a "versatile" barriers, it also has the effect of three other barrier. Most modern multi-processor support for the barrier (other types of barriers are not necessarily supported by all processors). Implementation of the barrier overhead will be very expensive, because the current processor typically want to write all the data in the buffer to refresh memory (buffer fully flush). At the same time this barrier also solve the above problems, to have to go before a c assignment, then insert before taking a LoadStore, you can read the latest to ensure that the value of a!

Guess you like

Origin juejin.im/post/5d3e5a9f6fb9a07ed6581b9e