Java Memory Model detailed

Source: Internet
Author: User

Memory model
The memory model describes the relationships between variables (instance fields, static fields, and array elements) in the program, as well as low-level details such as storing variables into memory and removing variables from memory in the actual computer system.

The processor architecture between the different platforms will directly affect the structure of the memory model.

In C or C + +, you can use the memory model under different operating platforms to write concurrent programs. However, this brings developers a higher learning cost.
In contrast, Java leverages the advantages of its own virtual machines, making the memory model not tied to a specific processor architecture and truly cross-platform.
(for different JVMs, such as the Hotspot JVM, JRockit, the memory model will vary)

Features of the memory model:
A, Visibility visibility (multi-core, multi-threaded data sharing)
B, ordering order (the operation on memory should be orderly)

Java memory model
According to the instructions in Java Language specification, there is a main memory in the JVM system (either main memories or Java Heap memory), and all variables in Java are stored in memory and shared for all threads.

Each thread has its own working memory (working memory), in which the working RAM is a copy of some of the variables in main storage, the operation of all variables by the thread is in working memory, the threads cannot be accessed directly from each other, and the transfer of variables needs to be done via main memory.

Among them, the variables in working memory, under multi-core processors, are mostly stored in the processor cache, which is not visible when the cache is not in memory.

How does jmm embody visibility (Visibility)?
In JMM, when variable values are modified by concurrent threads, the thread variables must be synchronized back to main memory before other threads can access them.

How does JMM manifest order (ordering)?
Use the synchronization mechanism or the volatile keyword provided by Java to ensure the order in which memory is accessed.

Cache Consistency (caches coherency)

What is cache consistency?
It is a cache-area structure that manages multiprocessor systems, which ensures that data is not lost or duplicated in the cache-to-memory transmission. (From Wikipedia)

For example, understand:
If a processor has an updated value for the variable in its cache, but has not been written to the main memory, the other processor may not see the updated value.

How to resolve cache consistency?
A, sequential consistency model:
Requires a processor to propagate the changed variable value immediately, and to ensure that the value is accepted by all processors before it can continue to execute other instructions.

B, Release the consistency model: (similar to JMM cache coherency)
Allows the processor to delay the change of variable values until the lock is released for propagation.

JMM Cache Consistency Model – "Happens-before ordering (pre-order)"

Example programs in general:

x = 0;
y = 0;
i = 0;
j = 0;

Thread A
y = 1;
x = 1;

Thread B
i = x;
j = y;

In the above program, if the thread A, a, and the non-guaranteed operation, then what is the value of the i,j?

The answer is, not sure. (00,01,10,11 may appear)
The Java synchronization mechanism is not used here, so the jmm order and visibility cannot be guaranteed.

Happens-before ordering (first occurrence sort) How to avoid this situation?
The sorting principle has been achieved:
A, in program order, each action in a thread occurs before every operation that occurs after the current operation.
b, the object Monitor's unlock occurs before the thread that waits to acquire the object lock.
c, a variable write operation for the Volitile keyword, which occurs before the read of the variable.
D, a Thread.Start () call to a thread occurs before all operations in the thread that is started.
E, all operations in the thread occur before all other threads are successfully returned from this thread's Thread.Join ().

To implement the Happends-before ordering principle, Java and JDK tools are available:
A, synchronized keyword
b, volatile keyword
C, final variable
D, Java.util.concurrent.locks pack (since JDK 1.5)
E, Java.util.concurrent.atmoic pack (since JDK 1.5)
...

Examples of Happens-before ordering are used:

(1) Get the lock of the object Monitor (lock)

(2) Emptying working memory data, copying variables from main memory to current working memory, i.e. synchronizing data (read and load)

(3) Execute code, change shared variable value (use and assign)

(4) Brush the working memory data back to main storage (store and write)

(5) Releasing the lock on the object monitor (unlock)

Note: 4, 52 of these steps are simultaneous.

The core of this is the second step, he synchronizes the main memory, that is, the result of the previous thread changes to the variable, can be learned by the current thread! (using the Happens-before ordering principle)

Compare the previous example
If multiple threads execute a piece of code that is not locked at the same time, it is possible that a thread has changed the value of the variable, but other threads are unable to see the change, and still operate on the old variable value, resulting in unpredictable results.

Double-checked locking failure of classic Java EE design mode
Double check locking failure problem has been one of JMM's unavoidable shortcomings. Understanding the DCL failure problem can help us to get into the jmm operation principle.

To demonstrate the DCL failure problem, first understand an important concept-lazy loading (lazy loading).

Examples of single-threaded lazy loading that are not singleton:

Class Foo{ Private ResourceRes= Null public resource ()  { // Normal deferred loading  if  (res == null)  res = new resource ();  return Res;}}          /span>                

Examples of non-singleton multithreaded lazy loading:

Class Foo{ Private ResourceRes= Null; public synchronized  Resource Getresource ()  {  //get instance operations using synchronous mode, low performance  if   (res ==  Null  res = new resource (); return Res;}}          /span>                

Examples of non-singleton DCL multithreaded Lazy loading:

Class Foo{ Private ResourceRes= Null; Public ResourceGetResource() { If (Res== Null) { //the synchronization mode is only used when the first initialization is initiated. synchronized (this Span class= "pun" >{ if (res == null)   { res = newresource (); } return Res;}}          /span>                 

Double-checked locking seems to be very perfect. Unfortunately, according to the Java language Specification, the above code is unreliable.

The 2 most important reasons for these problems are as follows:
1, the compiler optimizes the program instructions to speed up CPU processing.
2, multi-core CPU dynamically adjusts the order of instructions to speed up the parallel computing capability.

The order in which the problem occurs:
1, thread A, Discovery object not instantiated, ready to start instantiation
2, because the compiler optimizes the program directives, allowing the object to point a reference to a shared variable to a partially constructed object before the constructor is called, although the object is not fully instantiated, it is no longer null.
3, thread B, discovers that the partially constructed object is no longer null, and returns the object directly.

However, some well-known open source frameworks, including Jive,lenya, are also using the DCL model with no extreme exceptions.
Shows that the occurrence rate of DCL failure problem is still relatively low.
The next step is the choice between performance and stability?

Alternative Initialize-on-demand for DCL:

Public Class Foo { There is a static inner class that is loaded only if there is a reference Private Static Class Lazyfoo { public static foo Foo = new  foo (); } public static foo Getinstance () { return lazyfoofoo;}}          /span>                

Wikipedia's DCL explains:

Http://en.wikipedia.org/wiki/Double-checked_locking

The perfect solution for DCL:

http://www.theserverside.com/patterns/thread.tss?thread_id=39606

Summarize:
Multithreaded programming, for variables that have write operations, must ensure that all of their reference points are consistent with the data in main memory (consider using synchronization or volatile).

Java Memory Model detailed

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.