volatile and JMM

Volatile is a lightweight synchronization mechanism provided by the Java Virtual Machine

  • Ensure visibility
  • Prohibit command queuing
  • Does not guarantee atomicity

JMM (Java Memory Model) memory model itself is an abstract concept is not real, it describes a set of rules or the norms set by this specification defines a way to access the program.

JMM synchronization requirements

  • Before thread unlock the value of the shared variable must refresh back to main memory
  • Before locking thread, you must read the latest value of main memory to their working memory
  • Lock unlock is the same lock

Since the program is run entity JVM thread, and each thread is created JVM will create a working memory, working memory is private data area for each thread, and Java memory model stores all variables defined in the main memory, the main memory is shared memory region, all threads have access, but the thread operations on variables (reading assignment, etc.) must be made in the working memory.

 

First of all to variables from the main memory copy of their work memory space, then the variable operation, after the operation is completed will write back to main memory variables, you can not operate the main variables in memory, working memory is stored in the main memory a copy of a copy of the variable, as I said before, the working memory is private data area of ​​each thread, so different threads can not access each other's working memory, communication (by value) between the thread must be done by the main memory.

 

JMM three characteristics :

  • Visibility (Vol atile )
    • Once a variable is modified immediately notify all other thread updates the variable copy
  • Atomicity
    • Maintain the integrity of data consistency . When a thread is working, the middle can not be split, you need to complete the whole. At the same time either succeed or fail at the same time. (Volatile does not guarantee atomicity , available Atomic Integer )
  • Orderliness

 

volatile usage scenarios:

Singleton question:

public class Singleton02 {

  private static volatile Singleton02 instance = null;

  private Singleton02() {
    System.out.println(Thread.currentThread().getName() + "  construction...");
  }

  public static Singleton02 getInstance() {
    if (instance == null) {
      synchronized (Singleton01.class) {
        if (instance == null) {
          instance = new Singleton02();
        }
      }  
    }
    return instance;
  }
}

 

Double lock detection terminal (with instructions rearrangement problem) due to the implementation of the first detected, to read a particular instance in a thread is not null, the reference object instance may not complete the initialization.

  • instance = new Singleton() It can be divided into the following three steps

    1
    2
    3
    memory = allocate (); // 1. Space assignment 
    instance (memory); // 2. initialize the object
    instance = memory;! // 3. Set the memory address just assigned points instance, this time instance = null
  • Step 2 and Step 3 no dependency, and whether before or after the rearrangement rearrangement execution result of the program has not changed in single-threaded, so this optimization is allowed.

  • Rearrangement

    1
    2
    3
    = the allocate Memory ();   // assignment space 1. 
    instance = Memory; // 3. Set the memory address just assigned points instance, this time instance = null, but the object has not been initialized!
    instance (Memory); // 2. initialize the object
  • Examples of volatile so without returning is not empty, but may be instances uninitialized

 

Guess you like

Origin www.cnblogs.com/zzb666/p/11696260.html