Java Learning: JMM (Java memory model), volatile, synchronized, atomicxxx understanding

Source: Internet
Author: User
Tags thread class volatile

The JMM (Java memory model) memory models

Two images from the Internet:

As illustrated above, in a multi-core CPU system, each core CPU has its own cache, and then the computer motherboard also has a piece of memory-called the main (ie: memory). At work, the data in the CPU's cache is guaranteed to be consistent with the data in the master by a series of means (cachecoherence), more straightforward, cache to load data from the primary, after processing, but also save back to main memory.

That is, the various variables in Java (variable) are stored in main memory, and then each thread itself has its own working area (working memories), while working, the thread from the main memory of the variable copy load to its own working memory area, processing done, Then save back to main memory.

It seems to be clear that there is nothing to understand:),

The problem is, if there are two threads: Thread A and thread B, a read the variable x from main memory (to its own working area), is preparing to process, then B modifies the main memory of the variable x, thread A can see this change? (If you need to load the latest values from main memory in time), this problem is known as the visibility of shared variables.

Second, volatile, synchronized, atomicxxx

Directly on the code:

2.1 Version 1

Package test.cn.mwee.order.monitor;/** * Created under Banyan Tree Yang over on 2017/6/11. */public class ThreadTest extends Thread {    private static Boolean flag = FALSE;    public void Run () {        System.out.println ("T1:" + thread.currentthread (). GetId ());        while (!flag) {        }        System.out.println ("quit!");    }    public static void Main (string[] args) throws interruptedexception {        threadtest t1 = new ThreadTest ();        T1.start ();        Thread.Sleep (+);        Threadtest.flag = true;        System.out.println ("main:" + Thread.CurrentThread (). GetId ());}    }

ThreadTest is a thread class that has a static variable flag and then writes a main method to do the test.

Note: after the T1 boot completes, the main thread modifies the threadtest static variable value flag, at this time the T1 run method in the while loop, in fact, is not see The main thread to this value modification, so the program can never quit, Can't print out that line of quit.

2.2 Version 2

Package test.cn.mwee.order.monitor;/** * Created under Banyan Tree Yang over on 2017/6/11. */public class ThreadTest extends Thread {    private static Boolean flag = FALSE;    public void Run () {        System.out.println ("T1:" + thread.currentthread (). GetId ());        while (!flag) {            synchronized (class.class) {            }        }        System.out.println ("quit!");    }    public static void Main (string[] args) throws interruptedexception {        threadtest t1 = new ThreadTest ();        T1.start ();        Thread.Sleep (+);        Threadtest.flag = true;        System.out.println ("main:" + Thread.CurrentThread (). GetId ());}    }

The relative version of the 1,while Loop adds a synchronized synchronization code block, although there is no code inside, but run again, can normally quit (think why?) )

Answer: (also copied from the Internet)

The Synchronized keyword enforces a mutex so that a protected block of code can enter and execute only one thread at a time. It also takes another role: before the thread enters the synchronized block, it maps all the contents of the working memory to the main memory, then empties the working memory and copies the latest values from the main storage . When the thread exits the synchronized block, the values in the working memory are also mapped to the main memory, but the working memory is not emptied at this time. In this way, the values in the working memory are consistent with the values in the main memory, guaranteeing the consistency of the data! (In other words, the while in run sees a change in the value of the flag variable in main memory)

Study questions: If you write a line println print output in while{}, that is:

        while (!flag) {            System.out.println ("flag=" + flag);        }

Also can exit normally, leave everybody to think.

2.3 Version 3

Package test.cn.mwee.order.monitor;/** * Created under Banyan Tree Yang over on 2017/6/11. */public class ThreadTest extends Thread {    Private volatile static Boolean flag = FALSE;    public void Run () {        System.out.println ("T1:" + thread.currentthread (). GetId ());        while (!flag) {        }        System.out.println ("quit!");    }    public static void Main (string[] args) throws interruptedexception {        threadtest t1 = new ThreadTest ();        T1.start ();        Thread.Sleep (+);        Threadtest.flag = true;        System.out.println ("main:" + Thread.CurrentThread (). GetId ());}    }

The relative version of the 1,flag variable before the keyword volatile, it can guarantee the change of the variable, synchronization to other threads, that is, when other threads read flag, see is the latest change in value, and volatile can also prevent the command reordering . Run, also can print out the Quit, program exit.

Note: Volatile can only guarantee that the value of the variable seen by other threads is up-to-date, but does not guarantee atomicity (in other words, high concurrency is still not 100% guaranteed thread safety)

2.4 version 4

Package Test.cn.mwee.order.monitor;import java.util.concurrent.atomic.atomicboolean;/** * Created under Banyan Tree Yang over on 2017/6 /11. */public class ThreadTest extends Thread {    private static Atomicboolean flag = new Atomicboolean (false);    public void Run () {        System.out.println ("T1:" + thread.currentthread (). GetId ());        while (!flag.get ()) {        }        System.out.println ("quit!");    }    public static void Main (string[] args) throws interruptedexception {        threadtest t1 = new ThreadTest ();        T1.start ();        Thread.Sleep (+);        ThreadTest.flag.set (true);        System.out.println ("main:" + Thread.CurrentThread (). GetId ());}    }

Compared to the previous version, using the Atomicxxx series class in concurrent packages that can guarantee atomicity without synchronizing the lock, it is also possible to print out the quit, which is recommended.

If interested, you can look at the source of Atomicboolean, in fact, with the help of volatile and CAS to achieve, the source of a look will know, no longer verbose.

Java Learning: JMM (Java memory model), volatile, synchronized, atomicxxx understanding

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.