Dig into the memory model from Singleton mode (iv)----Java memory model

Source: Internet
Author: User
Tags visibility

Java Memory Model:

Java memory model is Java Memorymodel, referred to as JMM. JMM defines how the Java Virtual Machine (JVM) works in Computer memory (RAM).

The JDK1.5 version reconstructs the Java memory model and begins using the new JSR-133 memory model.

JMM defines the abstract relationship between threads and main memory: Shared variables between threads are stored in main memory (main memories), each thread has a private local memory, or called working memory, and local memory stores the thread to read/write a copy of the shared variable.

Note: Local memory is an abstract concept of JMM and is not really there. It covers caching, write buffers, registers, and other hardware and compiler optimizations.



Inter-thread communication:

1. Thread A flushes the updated shared variables in local memory A to the main memory.

2. Thread B into main memory to read shared variables that have been updated before thread A.


Visibility, atomicity, and ordering in the Java memory model

Visibility of:

Visibility refers to the visibility between threads, and the state of one thread modification is visible to another thread. That is, the result of a thread modification. Another thread can see it right away. For example: variables modified with volatile will have visibility. Volatile-modified variables do not allow the thread to cache and reorder internally, that is, to modify memory directly. So it is visible to other threads. But there is a problem to be aware of, and volatile can only make it visible to the content he modifies, but it does not guarantee that it is atomic. For example, volatile int a = 0, then there is an operation a++, this variable a has visibility, but a++ is still a non-atomic operation, that is, the operation also has a thread safety problem.

Volatile, synchronized, and final implementation visibility in Java.

Atomic nature:

Atoms are the smallest units in the world and are indivisible. such as A=0; (a non-long and double type) This operation is indivisible, then we say this operation is atomic operation. Another example: a++; This operation is actually a = a + 1; is divisible, so he is not an atomic operation. There is a thread-safety problem with non-atomic operations, and we need to use synchronous technology (sychronized) to turn it into an atomic operation. An operation is an atomic operation, so we call it atomic. The Java concurrent package provides some atomic classes, and we can read the API to understand the use of these atomic classes. For example: Atomicinteger, Atomiclong, atomicreference and so on.

Synchronized in Java and operation in lock, unlock guarantees atomicity. Volatile does not guarantee atomicity.

Order:

The Java language provides the volatile and synchronized two keywords to ensure the ordering of operations between threads, because it contains the semantics of "no order reordering" itself, and synchronized is made up of " A variable that allows only one thread to lock on it at the same time "this rule determines that two synchronization blocks holding the same object lock can only be executed serially.

8 basic operations in the Java memory model:

    • Lock: A variable that acts on the main memory and identifies a variable as a thread-exclusive state.
    • Unlock (Unlocked): Acts on the main memory variable, releasing a variable that is in a locked state, and the released variable can be locked by another thread.
    • READ: Acts on the main memory variable, transferring a variable value from main memory to the working memory of the thread for subsequent load actions to use
    • Load: A variable that acts on working memory, which places the value of a read operation from the main memory into a variable copy of the working memory.
    • Use: A variable that acts on the working memory, passing a variable value in the working memory to the execution engine, which is performed whenever the virtual opportunity is to a bytecode instruction that needs to use the value of the variable.
    • Assign (Assignment): A variable acting on a working memory that assigns a value to a working memory from the execution engine, and performs this operation whenever the virtual opportunity is assigned to a byte-code instruction that assigns a value to a variable.
    • Store: A variable acting on a working memory that transfers the value of a variable in the working memory to the main memory for subsequent write operations.
    • Write: A variable that acts on the main memory, which transfers the store operation from the value of a variable in the working memory to a variable in the main memory.

If you want to copy a variable from main memory to working memory, you will need to follow the read and load operations, and if you synchronize the variables from the working memory back to main memory, you should perform the store and write operations sequentially. The Java memory model only requires that the above operations must be executed sequentially, without guarantee that continuous execution is required. That is, between read and load, the store and write can be inserted between the other instructions, such as the main memory of the variable A, b access, the possible order is read A,read B,load b, load a.

The Java memory model also stipulates that when performing the eight basic operations above, the following rules must be met:

    • Does not allow one of the read and load, store, and write operations to appear separately
    • A thread is not allowed to discard its most recent assign operation, that is, the variable must be synchronized to main memory after it has changed in working memory.
    • A thread is not allowed to synchronize data from the working memory back to main memory for no reason (no assign operation has occurred).
    • A new variable can only be born in main memory, and it is not allowed to use a variable that is not initialized (load or assign) directly in working memory. That is, the assign and load operations must be performed before a variable is implemented with the use and store operations.
    • A variable allows only one thread to lock it at the same time, and lock and unlock must appear in pairs
    • If you perform a lock operation on a variable, the value of the variable in the working memory will be emptied, and the value of the variable will need to be re-executed before the execution engine uses the variable, either the load or the assign operation.
    • If a variable is not locked by the lock operation beforehand, it is not allowed to perform a unlock operation on it, nor is it allowed to unlock a variable that is locked by another thread.
    • Before performing a unlock operation on a variable, you must first synchronize this variable into main memory (perform store and write operations).

Memory barrier

The Java compiler inserts a memory barrier directive in place of the generated instruction sequence to suppress a particular type of handler reordering.

The Java memory model divides the memory barrier into Loadload, Loadstore, Storeload, and Storestore four types:

Loadload Barrier: For such a statement Load1; Loadload; Load2, the data to be read by the LOAD1 is guaranteed to be read before Load2 and subsequent read operations are accessed.

Storestore Barrier: For such a statement Store1; Storestore; Store2, the Store1 write operation is guaranteed to be visible to other processors before Store2 and subsequent write operations are performed.

Loadstore Barrier: For such a statement Load1; Loadstore; Store2, the data to be read is guaranteed to be read by the Load1 before Store2 and subsequent write operations are brushed out.

Storeload Barrier: For such a statement Store1; Storeload; Load2, ensure that Store1 writes are visible to all processors before Load2 and all subsequent read operations are performed. Its overhead is the largest of the four types of barriers.

The so-called JSR-133 memory model

Starting with JDK1.5, Java uses the JSR-133 memory model, and until now JDK1.8 still follows the JDK1.5 memory model, which is based on the concept of Happens-before to illustrate the memory visibility between operations, meaning that if the result of the first operation is visible to the second operation, Then the two operations must have a happens-before relationship, but they are not required to be in one thread.

The Happens-before rules are as follows:

1, program Order rule: each action in a thread is happens-before to any subsequent action in that thread.

2, monitor lock rule: the unlocking operation of a lock, happens-before the lock operation.

3,volatile domain rule: writes to a volatile domain, happens-before the subsequent read of this volatile field on any thread.

4, transitive rule: if Ahappens-before B, and B happens-before C, then a Happens-before c.

Note: There is a happens-before relationship between the two operations, which does not mean that the previous operation must be performed before the next operation! Only the result of the execution of the previous operation is required, which is visible for the latter operation, and the previous operation is sorted in order before the next operation.

How the JVM implements the memory model

The above-mentioned memory model, the popular point is that there is a memory space as main storage, shared variables are put in main memory, the thread each has its own local RAM, used to cache the variables used, the threads through main memory for data interaction.

The way the JVM implements this memory model is:

1, there is a memory space as main storage, called Heap memory,

2, the threads each have their own local memory, called the line stacks, also called the call stack.

3, line Cheng contains information about the method calls that are executed by the current thread, as well as local variable information for the current method.

4, each thread can only access its own line stacks, and cannot access the thread stacks of other threads.

5, all native variables of the original type (boolean,byte,short,char,int,long,float,double) are stored directly in the thread stack, independent of each other, but the copies of the original type can be transferred between the threads (or cannot be counted as shared).

6, objects of non-primitive types are stored in the heap, and references to this object are stored in the stack.

7, the original type in the object's member method is stored in the stack.

8, the object's member variables, including the original type and wrapper type, as well as variables of the static type, are stored in the heap along with the class itself.

9, if a thread wants to use the object's original type member variable, it will copy a copy to its own line stacks.

10, if a thread is going to use the object's wrapper type variable, it accesses the heap directly.


Dig into the memory model from Singleton mode (iv)----Java memory model

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.