Why volatile to ensure orderliness can not guarantee atomicity

For the three characteristics of memory model: order, atomicity, visibility.

We all know that volatile to ensure the visibility and order but can not guarantee atomicity, but why?

 

A atomicity, ordering, visibility

1, Atomicity:

(1) means atom represents - "inseparable";
(2) the entire operation will not be interrupted thread scheduler operation may be considered to be atomic . Atomicity is rejected cross multithreaded operation , whether mononuclear or polynuclear, having atomic amount, the same time only one thread to operate it . For example, a = 1 atomic operation, but a ++ a + = 1 and is not atomic operation.

2, visibility

Thread execution results in memory visibility to other threads.

After a volatile variable when modified, this variable writes, assembly instructions have a LOCK prefix instruction, the addition of this instruction will lead to two things:

  • After the modifications made to force the current processor data cache line is written back to system memory .
  • The write-back memory operation will cause the other processor caches invalid memory address, re-read from memory.

3, orderliness

Observed within the thread, all operations are ordered (i.e., the instruction does not cause any rearrangements difference before and Sequencing threaded program execution result). Observation another thread in a thread, all operations are disordered, the disorder is because of a command reordering. In the Java memory model, allowing the compiler and processor instruction reordering, the reordering process does not affect the implementation of single-threaded programs, but it will affect the accuracy of concurrent execution of multiple threads.

 

Second, two questions thread-safe execution and memory control visible

Execution control (synchronize): control code can only be performed sequentially (only be performed once a thread of execution) or may be multi-threaded execution.

Visibility of memory control (volatile): thread execution results in memory visibility to other threads. In a specific thread execution, it will first copy the data to main memory thread local (CPU cache), the results after the operation is completed brush from the thread to the local main memory.

volatile and synchronize two keywords that the above two effects.

  • synchronize keywords so that only one thread at a time can obtain the current variable, lock methods, classes, and other threads can not access, it can not synchronize concurrent execution, synchronizedwill create a memory barrier , memory barrier instructions to ensure that all CPU operating results will be directly brush to main memory , thereby ensuring the visibility of memory operation, but also makes all the operations of the first thread of the lock is obtained, are then obtained in the happens-before operating the lock in the thread, security and orderly, visibility, atomicity;
  • volatile by forcing the value of the current thread modified such that the write back mode memory and this value is invalid in the other thread to ensure its visibility by disabling instruction rearrangement ensure orderly manner, why can not guarantee specific properties in the next part of the discussion atoms.

 

Third, why can not guarantee atomicity volatile

For i = 1 this assignment, because of its own atomic operation, so there is no inconsistency in a multithreaded program, but i ++ for this complex operation, even with the volatile keyword modifications can not guarantee atomicity operation, may cause data inconsistencies.

 private volatile int i = 0;
 i++;

If you enable the 500 concurrent threads to execute the final result of this operation i ++ i is less than 500

i ++ operation may be broken into three steps: 

      1, thread reads the value of i 

      2, i for calculating self-energizing 

      3, back to refresh the value of i

Explain some online blog is:

Suppose a time i = 5, then there are two threads of the value of i is read from the main memory, then the value of i stored in this case are two threads 5, then A i of the self-thread by calculation, then B is also incremented to i be calculated, this time back to the two thread last Update value i is hosted 6 (two threads have been calculated should be finished 7) so that the volatile can not guarantee atomicity.

I understand is that:

Since i is modified volatile variables, then for the operation i should be visible between the threads ah, even A., B two threads simultaneously read the value of i is 5, but if i is executing the thread A after the operation will be set to the value of B i read the thread to be invalid and force B to re-read the new value of the i is 6 then will be increment operator fishes ah.

Later, referring to other blog finally figured out:

1, thread reads I 

2, TEMP = I + 1 

. 3, I = TEMP

When i = 5 , when A, B reads the two threads i values, then A thread executes temp = i + 1 operation, to be noted that at this time the i value has not changed, then thread B also performed temp = i + 1 operation, note that this case a, B stored in two threads i values are . 5 , TEMP  value is 6 , then a thread executes i = temp (6) operation, At this point i value immediately flushed to main memory and saved notify other threads i value is invalid, then B thread needs to re-read the i value then the time saved thread B i is 6 , while thread B saved temp also it is still 6 , a thread of execution and B i = temp (6), resulting in a less than expected results 1 .

 

Four difference, volatile and synchronized the

  1. volatile nature is telling jvm current variable values ​​in register (working memory) is uncertain, needs to be read from the main memory; synchronized current variable is locked, only the current thread can access the variables, other threads are blocked live .
  2. volatile level can only be used in a variable; the synchronized variables can be used in the methods, and the class level
  3. Modify visibility and atomicity is guaranteed and synchronized variables; volatile visibility can be achieved only modify variables, does not guarantee atomicity
  4. volatile will not cause obstruction thread; synchronized may cause obstruction thread.
  5. volatile variables are not labeled optimizing compiler; mark may be synchronized variable optimizing compiler

 

references:

java memory model: https://blog.csdn.net/suifeng3051/article/details/52611310

and synchronize the difference volatile: https://blog.csdn.net/it_manman/article/details/79497807

Why volatile is not guaranteed atomicity: https://blog.csdn.net/xdzhouxin/article/details/81236356  https://blog.csdn.net/ACreazyCoder/article/details/82047970

Guess you like

Origin www.cnblogs.com/simpleDi/p/11517150.html
Recommended