As mentioned earlier, the use of volatile does not guarantee the atomic operation of the state of the variable, so-called atomicity, is no longer
such as: i++ atomic problem, i++ operation actually divided into three steps "read-Change-write"
(1) Save the value of I (in a temporary variable)
(2) Increment I
(3) returns the saved value
When the i++ is executed under concurrent conditions,
Thread 1 executes i++, first obtains the value of I from main memory (assuming the initial values i=0), has not yet waited to execute i = i + 1, at this time thread 2 comes in, also obtains the value of I from main memory (0)
Then thread 1 Executes i = i + 1; (i=1) thread 2 then executes i = i + 1 (i=1), this result is wrong
Even if you use volatile to ensure the visibility of memory, it is useless, even if you modify in main memory, it will produce this error
At this point, the CAS algorithm can be used, the CAS algorithm is an optimistic lock (collision detection) (Hibernate optimistic lock is added a version field to determine whether the concurrency occurred)
CAS (COMPARE-AND-SWAP) algorithm guarantees the atomicity of data variables
CAS algorithms are hardware support for concurrent operations
The CAS consists of three operands:
*① Memory Value V
*② Pre-estimate A
*③ Update Value B
* When and only if v = = A, v = B; Otherwise, no action is taken.
Process Analysis: Also execute i++ under concurrent conditions
1, the thread 1 executes i++, first obtains the value of I from main memory (v=i=0) (set i=0), at this time thread 2 comes in, also obtains the value of I from main memory (0)
2, then thread 1 executes getandincrement, which is the comparison and substitution execution, (procedure: Read the value of I again from memory (a=i=0), let a (0) and V (0) Compare,
Discovery V==a, at which point B = i+1, updates the value of B to memory (V = B))
3, then thread 2 begins to execute getandincrement, that is, compare and replace execution together, the procedure is similar to the above, but read the value from memory, I value has become 1, that is, a value of 1
Compare A (1) to V (0) to find V!=a and perform no action
Note: The significance of comparing V to A is to determine if the value to be updated (v) has changed, and if no change has occurred, then V is updated, otherwise no action is taken
After the discovery of v!=a, unlike synchronize, there is no blocking, not waiting for the current thread to finish, and then by the CPU allocated time to the thread 2 to execute,
Instead of constantly circulating the request, and then to try again, and then to update, which is the CAS algorithm than the normal synchronous lock of the practice of higher efficiency reasons
With the CAS algorithm, when there are multiple threads accessing shared resources in memory, only one thread succeeds at a time, and all other threads fail
The Java.util.concurrent.atomic package provides some common classes of atomic operations : The CAS algorithm is used frequently to ensure the atomic operation of the variable state.
? Atomicboolean , atomicinteger , atomiclong , atomicreference
atomicintegerarray atomiclongarray
atomicmarkablereference
atomicreferencearray
? atomicstampedreference
L Core Method:boolean compareandset (Expectedvalue, Updatevalue) (also the core of CAs, i.e., compare and replace)
1 /*2 * One, i++ atomicity problem: i++ 's operation is actually divided into three steps "read-Change-write"3 * int i = ten;4 * i = i++;//105 * 6 * (1) Save the value of I (in a temporary variable)7 (2) Increment i8 (3) returns the saved value9 * Ten * Two, atomic variables: Some atomic variables are provided under the Java.util.concurrent.atomic package. One * 1. Volatile Guaranteed Memory Visibility A * 2. CAS (COMPARE-AND-SWAP) algorithm guarantees the atomicity of data variables - * CAS algorithm is hardware support for concurrent operation - * CAS consists of three operands: the *① Memory Value V - *② Pre-estimate A - *③ Update Value B - * If and only if V = = A, v = B; otherwise, no action is taken. + */ - + Public classtestatomic { A Public Static voidMain (string[] args) { at -Atomicdemo AD =NewAtomicdemo (); - for(inti = 0;i<10;i++) { - NewThread (AD). Start (); - } - } in } - to classAtomicdemoImplementsRunnable { + //Creating atomic Variables - PrivateAtomicinteger i =NewAtomicinteger (0); the @Override * Public voidrun () { $ Try {Panax NotoginsengThread.Sleep (200); -}Catch(interruptedexception e) { the + } A //View source you can find loops always call the Compareandset (Exceptionvalue,updatevalue) method, which is performed by comparing and replacing, the //and if it fails, it will keep trying to update it (using the CAS algorithm) . + System.out.println (I.getandincrement ()); - } $ $ -}
2. Atomic variable CAS algorithm