1 Public classVolatileTest2Implementsrunnable{2 volatile intResource = 0;3 4 Public Static voidMain (string[] args) {5VOLATILETEST2 VT =NewVolatileTest2 ();6 NewThread (VT). Start ();7 NewThread (VT). Start ();8 while(Thread.activecount () > 1){9 Thread.yield ();Ten } One System.out.println (vt.resource); A } - - @Override the Public voidrun () { - for(inti=0; i<100000000; i++){ -resource++; - } + } -}
In this example, although there is a volatile keyword in front of the resource, the run result is still not 200000000. Why is it? I want to share my point of view.
First, each thread has its own memory, and when they modify the resource, they first copy the data into their own memory, modify it, and then write back to the main memory. So if that's the case, there are a number of scenarios in which multiple threads can operate simultaneously, and here are 2 things
(2 of the N cases that occur when the volatile keyword is not added)
First case:
The second case
The above 2 cases will cause the T2 thread to write the resource back to the main memory when the T1 self-increment that operation is overwritten. Because T1 and T2 threads read the resource value of main memory is the same ... So the equivalent of T1 's self-increment is invalid.
When the resource is preceded by a volatile keyword:
With volatile modifiers, the thread reads the most recent value of the variable every time the variable is used.
Http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html
Therefore, the second case can be avoided after adding this keyword.
T1 resource will write back directly to the main memory, allowing the T2 read operation to read to the most recent value. The equivalent of resource++ and writeback main memory is the same transaction and cannot be delimited.
But it is still not possible to avoid the first situation.
In the first case, the thread T2 read resource occurs before the T1 resource self-increment, so when T1 is self-increasing it does not affect T2 in the resource thread memory. This is not contrary to volatile. If T2 read resource at this point, that's the newest value. But unfortunately he read it before T1, so the value of resource in T2 is still old. The T2 increment value is still overwritten when T1 writes back to main memory.
The above is my understanding.
volatile keyword Learning record 2