The lock provides two main features: Mutual exclusion (mutual exclusion) and visibility (visibility). Mutual exclusion allows only one thread to hold a particular lock at a time, so you can use this attribute to implement a coordinated access protocol to shared data so that only one thread can use that shared data at a time. Visibility is more complex, and it must ensure that the changes made to the shared data before the lock is released are visible to the other thread that subsequently acquired the lock-if there is no guarantee of this visibility provided by the synchronization mechanism, the shared variables that the thread sees may be pre-modified or inconsistent values, which can cause many serious problems.
As follows:
Import Java.util.concurrent.countdownlatch;import java.util.logging.level;import java.util.logging.logger;/** * * @ Author Kangjun */public class Counter { private volatile static int volatilevalue = 0; private static final Countdownlatch latch = new Countdownlatch (+); public static Void Inc () { try { thread.sleep (1*1000) } catch (Interruptedexception ex) { Logger.getlogger (Counter.class.getName ()). log (Level.severe, NULL, ex); } volatilevalue++; } public static void Main (string[] args) throws Interruptedexception {for (int j = 0; J < K; J + +) { new Thr EAD ((), { Inc (); Latch.countdown (); }). Start (); } Latch.await (); System.out.println ("Volatilevalue:" + volatilevalue);} }
The output is:
volatilevalue:993
Why not 1000?
Let's take a look at the memory allocations at the time of the JVM runtime. One of the memory areas is the JVM virtual machine stack, each thread runs with a line stacks, and the line stacks saves the thread runtime variable value information. When a thread accesses an object, the value of the variable that corresponds to the heap memory is found first through the object's reference, then the concrete value of the heap memory variable is load into the thread local memory, a copy of the variable is created, and then the thread is no longer related to the object's value in the heap memory variable, but instead directly modifies the value of the At some point after the modification (before the thread exits), the value of the thread variable copy is automatically written back to the object in the heap variable. This changes the value of the object in the heap. Here is a picture:
Where use and assign can occur more than once, but these operations are not atomic, that is, after the read load, if the main memory count variable changes, the value of the thread's working memory will not change because it has been loaded. So the calculated result will not be the same as expected, for volatile modified variables, the JVM virtual machine simply guarantees that the value from main memory loaded into the thread's working memory is up to date.
For example, if thread 1, thread 2 in the read,load operation, found that the value of count in main memory is 5, then the latest value will be loaded
After the thread 1 heap count is modified, it is write to main memory, and the count variable in main memory becomes 6
Thread 2 because the read,load operation has been performed, after the operation, the main memory will also be updated count of the variable value of 6
When two threads are modified with the volatile keyword in a timely manner, there is still a concurrency situation.
Reference: http://www.ibm.com/developerworks/cn/java/j-jtp06197.html
Http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html
Notes on using the volatile keyword in Java