Depth understanding of Java memory model (three) - sequential consistency

Order to ensure consistency with the data competition

When the program is not properly synchronized, the data will exist competition. java memory model specification defines competition data as follows:

  • Write a variable in one thread,
  • In another thread reading the same variable,
  • Read and write and are not synchronized to sort through.

When the code contains data competition, execution of the program tend to produce counterintuitive results (an example is the case of the previous chapter). If a multi-threaded program can synchronize correctly, this program will not be a competitive process data.

JMM memory consistency multithreaded programs synchronized correctly made the following guarantees:

  • If the program is properly synchronized, the execution will have the sequential consistency (sequentially consistent) - that is the result of program execution of the program in sequential consistency memory model is the same result (as we shall see immediately, which for programmer is a strong guarantee). Here's synchronization refers to synchronization in a broad sense, including the correct use of the common synchronization primitives (lock, volatile and final) of.

Sequential consistency memory model

Sequential consistency memory model is an idealized theoretical computer scientist Reference Model, which provides a strong guarantee for the visibility of memory programmer. Sequential consistency memory model has two main features:

  • All operations must be a thread of execution in program order.
  • (Regardless of whether the program synchronization) that all threads can only see a single sequence of operations performed. In sequential consistency memory model, each operation must be performed and the atom immediately visible to all threads.

Sequential Consistency memory model provided by the programmer to view the following:

Conceptually, the sequential consistency model has a single global memory, this memory can be connected to any one of a thread switch by swinging around. At the same time, each thread must be programmed in order to perform memory read / write operations. From the graph we can see that at any point in time at most only one thread can be connected to memory. When a plurality of concurrently executing threads, the switching device of FIG all threads can all memory read / write operations serialized.

To better understand, let's take a further explanation of the characteristics of the sequential consistency model by two diagrams.

Suppose there are two threads A and B are performed concurrently. Wherein A thread has three operations, their order in the program are: A1-> A2-> A3. Thread B has three operations, their order in the program are: B1-> B2-> B3.

Assume that the two threads used to monitor the correct synchronization: A thread releases the monitor after performing three operations, then thread B to acquire the same monitor. The program execution results in the sequential consistency model as shown below:

Now we assume that two threads do not synchronize, the following is a schematic diagram of the implementation of this program is not synchronized sequential consistency model:

No synchronization program in sequential consistency model, although the overall execution order is out of order, but all threads can only see a consistent overall execution order. FIG above example, thread A and B to see the order of execution are: B1-> A1-> A2-> B2-> A3-> B3. We have been able to get this guarantee because sequential consistency memory model each operation must be immediately visible to any thread.

However, the JMM would not have this guarantee. JMM is not a synchronization program, not only in the overall implementation of the order is out of order, but the order thread sees all actions may also be inconsistent. For example, in the current thread the written data cached in local memory, and has not refreshed before the main memory, the write operation is visible only to the current thread; viewed from the perspective of other threads will think that this simply has not write the execution of the current thread. After the refresh only the current thread in the local memory data written to main memory, the write operation to be visible to other threads. In this case, the current thread and the other thread sees the operations performed sequentially inconsistent.

The effect of sequential consistency synchronization program

Here we ReorderExample monitor to synchronize with the previous example program to see how to properly synchronize the program with sequential consistency.

Consider the following sample code:

class SynchronizedExample {
int a = 0;
boolean flag = false;

public synchronized void writer() {
    a = 1;
    flag = true;
}

public synchronized void reader() {
    if (flag) {
        int i = a;
        ……
    }
}
}

After the sample code above, a thread of execution, assuming A writer () method, B thread execution Reader () method. This is a multi-threaded program properly synchronized. The JMM specification, an execution result of the program will have the same result of executing the program in the sequential consistency model. The following are two memory model program execution timing comparison chart:

In the sequential consistency model, all operations in light of a program executed in serial order. In JMM, the code reordering critical region can (but does not allow the code JMM critical region "escaping" to the outside of the critical zone, that would undermine the semantics of the monitor). JMM will do some special treatment in entering and exiting the monitor monitors two key points of time, so that the thread has the same memory sequentially consistent view (the details described herein will be) at both time points. Although A thread in the critical region do reordering, but due to the nature mutually exclusive monitor the implementation, where the thread B can not "observed" to the thread A reordering in a critical region. This reordering only improves efficiency, but did not change the results of the program.

From here we can see the JMM basic policies on the concrete realization of: without changing the (correct synchronization) under the premise of the program execution results, open the door to possible optimizing compilers and processors.

The execution characteristics of the program are not synchronized

For multi-threaded programs are not synchronized or not properly synchronized, JMM provides only minimal security: to read the value of the thread execution, before or values ​​written a thread, either the default values ​​(0, null, false) , the read value read does not thread JMM ensure nothing (out of thin air) coming out. In order to achieve a minimum security, JVM heap allocated objects in the first memory space is cleared, and then will assign an object above (inside the JVM will synchronize the two operations). Therefore, when the assignment to clear memory space (pre-zeroed memory), Domain default initialization has been completed.

JMM does not guarantee the execution result of the program is not synchronized with the program execution results in the sequential consistency model. Because not synchronized program execution in sequential consistency model, on the whole is chaotic, unpredictable results of its execution. Ensure the implementation of the results of the program are not synchronized in both models of the same meaningless.

And sequential consistency models, when no synchronization procedure in the JMM, on the whole is disordered, its execution results are unpredictable. At the same time, are the following differences in execution characteristics of the program is not synchronized in both models:

  1. Operating model in order to ensure the consistency of single-threaded program will be executed sequentially, while the JMM does not guarantee operation within a single thread is executed (such as multi-threaded programs above correctly synchronized reordering the critical region) program order. It has already been mentioned, not repeat them here.
  2. Sequential consistency model to ensure that all threads can only see the same sequence of operations performed, while JMM does not guarantee that all threads see a consistent view of operational execution order. This front has also been talked about, not repeat them here.
  3. JMM does not guarantee the long reading of 64-bit type and double-type variable / write operations are atomic, the sequential consistency model to ensure that all of the memory read / write operations are atomic.

The third difference is closely related to the working mechanism of the processor bus. In the computer, data transfer between the processor and memory via the bus. Each data transfer between the processor and memory are accomplished through a series of steps, this series of steps is called a bus transaction (bus transaction). Bus transactions include read transactions (read transaction) and write transactions (write transaction). Memory read transaction to transfer data from the processor, a write transaction transfers data from memory to the processor, each transaction is a read / write memory physically contiguous one or more words. The key here is that the bus will attempt to synchronize concurrent use of bus transactions. During a processor executes the bus transaction, the bus would ban all other processors and I / O devices to perform memory read / write. Let's work through a schematic diagram to illustrate the mechanism of the bus:

, Assume processor A, B and C at the same time, then bus arbitration (bus arbitration) the bus will compete ruling bus transaction initiated above, where we assume that the decision processor bus A win the competition in the arbitration ( bus arbitration ensures that all processors have equitable access memory). A processor at this time to continue its bus transactions, while the other two processors will have to wait for the bus completion A transaction processor memory accesses can begin again. A hypothesis during the execution processor bus transaction (regardless of whether the bus transaction is a read transaction or write transaction), D processor launched a bus transaction to the bus, this time the request processor bus D will be prohibited.

The working mechanism of a bus can put all processors to access memory in a serial manner of execution; at any point in time, at most only one processor can access the memory. This feature ensures that the memory read bus into a single transaction / write operation is atomic.

In some 32-bit processors, if desired read / write operations on 64-bit data are atomic, the cost will be relatively large. To take care of such processors, java language specification encouraged, but not force the JVM 64 of the double long variable and variable read / write atomic. When the JVM is running on this processor, put a 64-bit long / double variable read / write operation is split into two 32-bit read / write operation is performed. These two 32-bit read / write operations may be assigned to different bus transaction is performed, this time on the 64-bit variable read / write are not atomic.

When the memory operation does not have a single atomic will likely have unintended consequences. Consider the following diagram:

, Assuming the processor to write a long variable A above, while the processor B to read the long variable. A 64 bit processor write operation is split into two 32-bit write operations, and the two 32-bit writes are assigned to different write transaction is performed. Meanwhile processor B 64-bit reads split into two 32-bit read operation, and the two 32-bit read operation is assigned to the same read transaction executed. When processor A and B according to the timing diagram to execute, the processor will see only the processor B A "half-written" invalid value.

 

 

Published 136 original articles · won praise 6 · views 1489

Guess you like

Origin blog.csdn.net/weixin_42073629/article/details/104741472