Memory semantics for Java memory model-volatile

Source: Internet
Author: User
Tags flushes volatile

An introduction

I heard that the volatile keyword was controversial before Java 5, so this article does not discuss volatile before version 1.5. This article is mainly aimed at 1.5 after the JSR-133 for volatile to do a strengthened understanding.

Characteristics of two volatile

  To the point, the volatile variable itself has the following characteristics:

    • Visibility of (the most important feature). To read a volatile variable, you can always see (any thread) the last write to the volatile variable.
    • Atomic Nature . The read/write for any single volatile variable (including 64-bit long and double types) is atomic. But a compound operation of type a++ is not atomic.

The following is a case to prove the visibility, first of all to see whether a common variable can guarantee the visibility of:

3 classExample {4 private Boolean stop = False; 5 public voidExecute () {6 int i = 0; 7 System.out.println ("Thread1 start loop.")); 8 while (!Getstop ()) {9 i++; 10}11 System.out.println ("Thread1 finish loop,i=" + i); }13 public boolean  getstop () {return stop;//read to normal variable }16 public void Setstop (Boolea n  flag) {this.stop = flag;//write to normal variable }19 }20 public class  Volatileexample {$ public static void Main (string[] args) throws  Exception {final Example Example = new  Example (), Thread t1 = new Thread (New  Runnable () { @Override25 public void  run () {Example.execute  (); }28 });  T1.start (), Thread.Sleep (+ ), SYSTEM.OUT.PRINTLN ("The main thread is about to set the stop value to True ..." ); 33 Example.setstop (True ); System.out.println ("The main thread has the stop value:" +  example.getstop ()); System.out.println ( "The main thread waits for thread 1 to finish ..." ); T1.join (); System.out.println ("Thread 1 has been executed, the entire process is finished ..." ); }40}  

The above program means: Let the thread 1 execute first and then the main (main) thread to modify the flag to see if the child threads can jump out of the loop. After executing the program, it is found that the program is not finished, but waits for thread 1 to finish executing. This means that the main thread modifies the stop variable and is not visible to thread 1, so the normal variable is not guaranteed to be visible .

When you put the variable stop with the volatile modifier, the main thread modifies the stop variable to be immediately visible to thread 1 and terminates the program, which proves that the volatile variable is of a visibility nature . The following modified results.

Atomic properties have been made clear (for arbitrary (including 64-bit long and double types) of a single volatile variable read/write has atomicity), remember that a single volatile variable read or write to be atomic (if you want to test, Change the volatile variable of the above case to the Long/double type and test the logic just to run it on the x86 machine. Because there is no guarantee of the atomicity of the long type and the double type on x86 machines, the specific reason is explained in the Sequential consistency section of the Java memory model. In addition, no composite operation guarantees atomicity , such as A++,a = a+1, a = B. Pay particular attention to a = B, which actually contains 2 operations, which first reads the value of B and writes the value of B to the working memory, although the 2 operations that read the value of B and write the value of B to working memory are atomic operations, but together it is not atomic .

  A good way to understand the volatile nature is to have a single read/write of the volatile variable as a synchronization of these individual read/write operations using the same lock.

Three volatile write-read established Happens-before relationship

This is explained in detail in the Happens-before rule.

Four volatile write-read memory semantics
    • When a volatile variable is written, JMM flushes the shared variable value in the local memory corresponding to that thread to the main memory .

    • When a volatile variable is read, JMM will place the local memory corresponding to that thread as invalid . The thread next reads the shared variable from the main memory .

  As an example of the above Volatileexample program, the main thread has flushed the stop value to main memory when the main thread has modified the stop and the child thread has not read the stop. It is as follows:

When a child thread reads, the local memory is set to be invalid and read directly to the main memory. (Here the main thread and the child thread can understand that there is no parent-child relationship for two normal threads) as follows:

Implementation of five volatile memory semantics

To implement volatile memory semantics, JMM restricts the reordering of these two types separately. is the volatile reorder rules table specified by the JMM for the compiler.

    • When the second operation is a volatile write operation, it cannot be reordered, regardless of the first operation (normal read or write or volatile read/write). This rule ensures that all operations before the volatile write are not reordered after the volatile write;
    • When the first action is a volatile read operation, it cannot be reordered, no matter what the second action is. This rule ensures that all operations after the volatile read are not reordered until the volatile reads;
    • When the first action is a volatile write operation, the second operation is a volatile read operation and cannot be reordered.

In order to implement volatile memory semantics, the compiler inserts a memory barrier in the instruction sequence when generating bytecode (as mentioned in JMM and has a description of the role of several barriers, read carefully) to suppress a particular type of handler to reorder. The following is a conservative policy-based JMM memory barrier insertion strategy:

    • Insert a storestore barrier in front of each volatile write operation (prohibit the preceding write and volatile write reordering).

    • Insert a storeload barrier after each volatile write operation (prohibit volatile writes with the possible read and write re-ordering later).

    • Insert a loadload barrier after each volatile read operation (disable volatile reads and reorder subsequent read operations).

    • Insert a loadstore barrier after each volatile read operation (disable volatile reads and reorder subsequent writes).

The emphasis is on the storelaod barrier, which is the key to ensuring visibility because it flushes all the data in the write buffers before the barrier into main memory . The above-mentioned memory barrier insertion strategy is very conservative, but it can guarantee the correct volatile semantics in any processing platform and in any program. The following is a conservative strategy (why conservative, because some of the actual scenarios can be omitted), the volatile write operation after inserting the memory barrier after the generated instruction sequence:

The Storestore barrier ensures that all normal writes preceding it are visible to any processor before volatile writes (flushing it to main memory). In addition, volatile writing is followed by a storeload barrier that prevents volatile writes from being reordered with the possible subsequent read or write operations. Because the compiler often cannot accurately determine whether a storeload barrier needs to be inserted after a volatile write (for example, a volatile write method immediately return) in order to ensure the correct implementation of volatile memory semantics, JMM adopted a conservative strategy: insert a storeload barrier behind each volatile write . Because of the common pattern of volatile write-read memory semantics: A write thread writes a volatile variable, and multiple degrees threads read the same volatile variable. When the number of read threads significantly exceeds the write thread, choosing to insert the storeload barrier after volatile writes will result in a considerable increase in execution efficiency. From here you can see that JMM is a feature of the implementation: first of all to ensure correctness, and then to pursue efficiency (in fact, we work in the same code).

Below is the sequence of instructions produced by the volatile read insert memory barrier under the conservative strategy:

The memory barrier insertion strategy described above for volatile write and volatile reads is very conservative. In practice, as long as the volatile write-read memory semantics are not changed, the compiler can ignore unnecessary barriers depending on the situation. In the JMM Foundation, there is a reference to the individual processor support for each barrier, where the x86 processor will only reorder write-read operations.

Vi. Summary

The main function of volatile is to have visibility and atomicity (a single variable), and its implementation principle is to use barriers to ensure implementation. If you want to master it, you should do more coding of the relevant scene, the classic scene is: The amount of state markers, volatile mode double check and so on.

If there are errors above, please point out, welcome to discuss, thank you!

Memory semantics for Java memory model-volatile

Related Article

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.