A brief analysis of Java memory model and volatile keywords

Source: Internet
Author: User
Tags volatile

volatile关键字在java并发编程中是经常被用到的,大多数朋友知道它的作用:被volatile修饰的共享变量对各个线程可见,volatile保证变量在各线程中的一致性,因而变量在运算中是线程安全的。但是经过深入研究发现,大致方向是对的 ,但是细节上不是这样。

First, it leads to the effect of volatile.
Scenario: When thread a encounters a condition, it wants thread B to do something. A scene like this should be a regular encounter, let's take a look at the analog code:

  Package Com.jack.jvmstudy;public class Testvolatile extends thread{private Boolean isrunning = true;//the identity thread is    No Run public boolean isrunning () {return isrunning;    The public void Setrunning (Boolean isrunning) {this.isrunning = isrunning;        } @Override public void Run () {while (isrunning ()) {//If IsRunning = True This will fall into a dead loop}    System.out.println ("Loop thread end ...");        } public static void Main (string[] args) {testvolatile TV = new Testvolatile ();        thread T1 = new thread (TV);        T1.start ();//Start thread, enter the infinite loop at this time try {//Let the main thread pause for 1 seconds thread.sleep (1000);        } catch (Interruptedexception e) {e.printstacktrace ();    } tv.setrunning (false);//The main thread changes isrunning to False to terminate the loop thread System.out.println ("Main thread end ..."); }}

Running this program finds that the main thread is finished, but the loop thread is still circulating, which is the correct result, though not the result we want to see. Our goal is to let the main thread terminate the execution of the loop thread, but the above program obviously does not, to achieve this effect, there are many ways, today we look at using the volatile keyword, only need to add volatile isrunning, and then execute the program, We found that the loop thread terminated, is not very magical, in fact, we all know that this is not magic, the reason is very simple, is the top of that paragraph, but a bit deeper? The memory model of Java is involved.

Java Memory Model:

Forgive me for drawing skills!!!

The main goal of the Java memory model is to define the access rules for each variable in the program, that is, the underlying details of storing variables in the virtual machine into memory and removing variables from memory. The variables here differ from those in Java programming, including instance fields, static fields, and elements that make up the array object, but not local variables and method parameters, because the latter is thread-private and will not be shared, and there is no competition problem naturally.

The following memory model is based on the above, to see how the memory between the interactive operation.
A new variable is first created in main memory, and if each thread uses that variable, it retains a copy of the variable in its own workspace. After the thread modifies the copy, it synchronizes to the main memory immediately, but if it is not specially handled, the other thread is still the original value, which is an expired value. Take the top example, first the shared variable isrunning=true is born in the main memory, then the main thread and the loop thread each keep a copy, then the main thread modifies the value of isrunning and synchronizes back to the main memory, but the loop thread is still the original value, so it causes the result of the dead loop.
The next step is the volatile, variable-modified variables are visible to each thread, meaning that variables modified by the volatile, each thread to use it, will go to the main memory to take the latest value, instead of directly using the copy, This ensures that the variable is consistent across threads. Although volatile modified variables ensure that each thread gets the latest data, it does not mean that operations based on volatile variables are safe in concurrency. First on the code

  Package Com.jack.jvmstudy;public class TestVolatile2 {public volatile static int race = 0;    public static void Increase () {race + +;        } public static void Main (string[] args) {thread[] threads = new THREAD[20];                for (int i = 0; i <; i++) {threads[i] = new Thread (new Runnable () {@Override                    public void Run () {for (int i = 0; i< 10000; i++) {increase ();            }                }            });        Threads[i].start ();        }//waits for all cumulative threads to end while (Thread.activecount () > 1) thread.yield ();    System.out.println ("race =" + race); }}

Running the above program, we expect to output 20000, but after execution, we find that this is not the case, and the distance is very large. Why is it?
Because race + + is not an atomic operation, although race is volatile modified to ensure that the main memory variables are modified the first time to reflect the various threads, but the + + operation is not a complete step, simple analysis, race + + operation is divided into three steps, a, to get the value of race; b, The value of race is added 1;c, race value is returned. Because of the volatile effect, each time the thread gets the value of race is up to date, but a thread may be suspended after executing a, the other thread completes the race++ operation and writes the value to the main memory, when the thread then executes the B operation, the value of race has expired. , and then write the value of the main memory is small. It is simple to add the Synchronized keyword to the increase () method to ensure that the race++ is an atomic operation.

Well, today, the analysis of volatile is here, this post mainly refer to the "in-depth understanding of Java Virtual Machine", just made a simple overview, interested friends can read the original book.

A brief analysis of Java memory model and volatile keywords

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.