In the current Java memory model, threads can store variables in local memory (such as the machine's registers), rather than read and write directly in main storage.
This can cause a thread to modify the value of one variable in main memory, while another thread continues to use its copy of the variable value in the register, resulting in inconsistent data.
To solve this problem, just like in this program, the variable is declared volatile (unstable), which indicates that the JVM, this variable is not stable, each use it to the main memory to read. Generally speaking, the flags shared between tasks in a multitasking environment should be modified with a volatile modifier.
A volatile-modified member variable forces the value of the member variable to be reread from shared memory each time it is accessed by the thread. Also, when a member variable changes, forcing the thread to write the change back to the shared memory.
So at any moment, two different threads always see the same value for a member variable.
Code:
Public classCounter { Public Static intCount = 0; Public Static voidInc () {//The delay is 1 milliseconds, making the result obvious Try{Thread.Sleep (1); } Catch(Interruptedexception e) {} count++; } Public Static voidMain (string[] args) {//Start 1000 threads at the same time to perform i++ calculations to see the actual results for(inti = 0; i < 1000; i++) { NewThread (NewRunnable () {@Override Public voidrun () {counter.inc (); }}). Start (); } //there may be different values for each run, which may beSYSTEM.OUT.PRINTLN ("Run Result: counter.count=" +counter.count); }}
Running Result: counter.count=980
View Code
Add volatile
Public classCounter { Public volatile Static intCount = 0; Public Static voidInc () {//The delay is 1 milliseconds, making the result obvious Try{Thread.Sleep (1); } Catch(Interruptedexception e) {} count++; } Public Static voidMain (string[] args) {//Start 1000 threads at the same time to perform i++ calculations to see the actual results for(inti = 0; i < 1000; i++) { NewThread (NewRunnable () {@Override Public voidrun () {counter.inc (); }}). Start (); } //there may be different values for each run, which may beSYSTEM.OUT.PRINTLN ("Run Result: counter.count=" +counter.count); }}
Result:
Running Result: counter.count=801
View Code
The results of the operation is still not what we expected 1000, let us analyze the reasons below
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 first found by the object's reference, and then the heap memory
The specific value of the variable is load into the thread's local memory, a copy of the variable is created, and then the thread is no longer related to the object in the heap memory variable value, but directly modifies the value of the replica variable.
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.
However, these operations are not atomic, that is, after read load, if the main memory count variable is modified, the value in the thread's working memory will not change because it has been loaded, so the computed result will not be the same as expected
For volatile-modified variables, the JVM virtual machine simply guarantees that the value from main memory load to the working memory of the thread 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.
Volatile and staticstatic refer to static members of a class, where shared volatile between instances is related to Java's memory model, which loads variables from main memory into the thread's working memory, creates a copy, and writes back at some point. Valatile refers to the value of the main memory read each time, and updates are immediately written back to the main memory. Understanding these two points, step by step to explain your confusion: "Since static is guaranteed uniqueness": static guaranteed uniqueness, which refers to statically decorated statics is unique, and multiple instances share the only member. "Then he is visible to multiple threads": Here, Static is not very much related to threads, it should be said that multiple object instances are visible. You say that there is nothing wrong with being visible to multiple threads, because static variables are globally visible, but turning this understanding into thread-on-line text is a cause of confusion. "Volatile guarantees visibility between threads": Because the thread sees the volatile variable to read the most recent value of the main memory, instead of having to play with the variable copy inside, it guarantees the visibility of the valatile variable between the threads. "Then when the modification is atomic, it will be guaranteed to be unique": "uniqueness" at this point, meaning that each thread can read the only up-to-date main memory variable, eliminating the "non-uniqueness" between threads that the thread's working memory load variable copy might bring. The meaning of "uniqueness" here is not the same as the first sentence, "uniqueness". "I think the two are about the same as I understand. In fact, the "scene" to solve the problem is completely different. The biggest reason for understanding confusion is that these two scenarios are slightly similar, confusing: Scenario 1: Instances of each class share unique class static variable scenario 2: Each thread reads the value of a unique, up-to-date main memory variable together
View Code
Synchronized is more expensive than volatile, and volatile is capable of using volatile.
Volatile does not guarantee atomic manipulation, so it is easy to read dirty data.
Http://www.ibm.com/developerworks/cn/java/j-jtp06197.html
Http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html
http://blog.csdn.net/feier7501/article/details/20001083
https://www.zhihu.com/question/41579791
Java volatile Keywords