Atomic operations: 507,383,170 can not be split (interrupted) or of a series of operations is called an atomic operation.
Atomic atomic operation 12 main categories, four types of atomic update mode, update the basic types of atoms, atomic update array, field updates atoms, atomic update reference. Atomic package wrapper classes are basically used Unsafe implemented.
Basic types: AtomicInteger, AtomicLong, AtomicBoolean;
Reference types: AtomicReference, ABA examples of AtomicReference, AtomicStampedRerence, AtomicMarkableReference;
Array type: AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray;
Attribute atom modifier (Updater): AtomicIntegerFieldUpdater, AtomicLongFieldUpdater, AtomicReferenceFieldUpdater;
1, the basic atomic update typeclasses
Here we look at an example of each type:
/** * <p>Title: AtomicIntegerTest.java</p > * <p>Description: </p > * <p>Copyright: NTT DATA Synergy All Rights Reserved.</p > * <p>Company: www.synesoft.com.cn</p > * <p>@datetime 2019年8月9日 上午8:01:30</p > * <p>$Revision$</p > * <p>$Date$</p > * <p>$Id$</p > */ package com.test; import java.util.concurrent.atomic.AtomicInteger; /** * @author hong_liping * */ public class AtomicIntegerTest { static AtomicInteger ai=new AtomicInteger(); public static void main(String[] args) { for(int i=0;i<10;i++){ new Thread(new Runnable() { @Override public void RUN () { ai.incrementAndGet (); } .}) Start (); } // the try { // the Thread.sleep (100); //} the catch (InterruptedException E) { // e.printStackTrace (); //} System.out.println ( "result of the following cycle:" + ai.get ()); } }
// test results
rotation result is as follows: 9
results after cycles were as follows: 10
According to the above code, we run more than a few times, you will find the test results for a moment while the code is 9 is 10, not 10, why, because the thread has not finish, I had the following play out, let the thread sleep We can solve this problem.
Here we look at atomic the ABA problem, the problem during the interview often asked.
/** * <p>Title: AtomicTest.java</p > * <p>Description: </p > * <p>@datetime 2019年8月8日 下午3:40:37</p > * <p>$Revision$</p > * <p>$Date$</p > * <p>$Id$</p > */ package com.test; import java.util.concurrent.atomic.AtomicInteger; /** * @author hong_liping * */ public class AtomicAbaTest { private static AtomicInteger ato=new AtomicInteger(1); public static void main(String[] args) { Thread mainT=new Thread(new Runnable() { @Override public void run() { int a=ato.get(); System.out.println(Thread.currentThread().getName()+"原子操作修改前数据"+a); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } boolean successFlag=ato.compareAndSet(a, 2); if(successFlag){ System.out.println(Thread.currentThread().getName()+"原子操作修改后数据"+ato.get()); } } },"mainT"); Thread otherT=new Thread(new Runnable() { @Override public void run() { int b=ato.incrementAndGet();//1+1 System.out.println (. Thread.currentThread () getName ( ) + " atomic increment operation after the data" B +); B = ato.decrementAndGet (); // 2-1 System.out.println (Thread.currentThread () .getName () + "Save atomic operation since the data" B +); } }, "OtherT"); mainT.start (); otherT.start (); } }
test results:
After OtherT 2 atomic increment data
MAINT atomic operation before modification data 1
OtherT atomic decrement data after a
post-atomic operation to modify the data MAINT 2
According to the above operation, we can see that the operation AtomicInteger increment, decrement, etc. Alternatively value. Here it should be noted that there is a problem atomic operation ABA, ABA problem is that the phenomenon of: performing value after completion mainT 2 (alternative 2), otherT 2-1 when executed is incremented to 2 (1 + 1 )the result of. Used in these two threads 2 is not the same 2, the equivalent of a loophole, the equivalent of saying you stole 10 million account from Wang Jianlin to invest in, so you better back this investment, and then you this 10 million dozen back to Wang Jianlin account, this whole process did not find Wang Jianlin, you did not record the whole operation, so for Wang Jianlin, who had not lost his money, or put there. When it is clear that the best way to solve this problem is the ABA every step of the operation are to make a mark, the equivalent of a bank of water, so you steal money, pay back the money out of the whole process there is a one in, just to see Wang Jianlin I find that the total gold has not changed, but the operating records show that my money had been stolen by the people and then come back up. That's where AtomicStampeReference.
2, reference type atomic update
Next we look at AtomicStampedReference test class:
/** * <p>Title: AtomicStampedReference.java</p > * <p>Description: </p > * <p>@datetime 2019年8月9日 上午8:35:56</p > * <p>$Revision$</p > * <p>$Date$</p > * <p>$Id$</p > */ package com.test; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicStampedReference; /** * @author hong_liping * */ public class AtomicStampedReferenceTest { private static AtomicStampedReference<Integer> asf=new AtomicStampedReference<Integer>(1, 0); public static void main(String[] args) { Thread mainT=new Thread(new Runnable() { @Override RUN void public () { int = asf.getStamp Stamp (); . System.out.println (Thread.currentThread () getName () + "atomic data before modification" asf.getReference + () + "_" + Stamp ); the try { the Thread.sleep (1000); } the catch (InterruptedException E) { e.printStackTrace (); } // At this point expectedReference not changed, but the stamp has been modified, so CAS failure boolean successFlag = asf.compareAndSet (. 1, 2, Stamp, Stamp +. 1); IF (successFlag) { . System.out.println (Thread.currentThread () getName () + "the atomic modified data" + asf.getReference () + "_" + Stamp); } the else { System.out.println(Thread.currentThread().getName()+"cas操作失败"); } } },"mainT"); Thread otherT=new Thread(new Runnable() { @Override public void run() { int stamp=asf.getStamp(); asf.compareAndSet(1, 2, stamp, stamp+1); System.out.println(Thread.currentThread().getName()+"原子操作自增后数据"+asf.getReference()+ "_"+asf.getReference()); asf.compareAndSet(2, 1, stamp, stamp+1); System.out.println (. Thread.currentThread () getName ( ) + " Save the data from the atomic operation" asf.getReference + () + "_"+stamp);; } }, "OtherT"); mainT.start (); otherT.start (); } } // test results: MAINT atomic operation before modification data 2_0 OtherT atomic increment operation after data 2_2 OtherT Save the data from the atomic 2_0 mainTcas operation failed
Next we look at a case of AtomicIntegerArray
/** * <p>Title: AtomicArrayTest.java</p > * <p>Description: </p > * <p>@datetime 2019年8月10日 上午9:45:49</p > * <p>$Revision$</p > * <p>$Date$</p > * <p>$Id$</p > */ package com.test; import java.util.concurrent.atomic.AtomicIntegerArray; import com.sun.org.apache.bcel.internal.generic.NEWARRAY; /** * @author hong_liping * */ public class AtomicArrayTest { static int[] array=new int[]{1,2,3}; static AtomicIntegerArray aia=new AtomicIntegerArray(array); public static void main(String[] args) { aia.getAndSet(1, 5); System.out.println(aia.get(1)); System.out.println (Array [. 1]); IF (aia.get (. 1) == Array [. 1]) { System.out.println ( "value of the atomic array in the array is equal to"); } the else { System.out.println ( "values in the array atoms and not equal to the array "); } } }
results:
. 5
2
is not equal to the values in the array of arrays atoms in
The code can be seen from the above atomic array with the same value index I defined data itself is not the same, and why, we look at the data source you will find not atomic operation I define the variable itself, It is the first copy, and then the operation is a copy version.
AtomicIntegerArray public (int [] Array) { // the Visibility Guaranteed by Final Field Guarantees this.array array.clone = (); // array initialization time copying }
public final int getAndSet(int i, int newValue) { return unsafe.getAndSetInt(array, checkedByteOffset(i), newValue); }
Atomic operation used when performing data type magic Unsafe.
4, atomic update field class
Next we look at AtomicIngerFieldUpdater
/** * <p>Title: AtomicIntegerFieldUpdateTest.java</p > * <p>Description: </p > * <p>@datetime 2019年8月10日 上午10:02:22</p > * <p>$Revision$</p > * <p>$Date$</p > * <p>$Id$</p > */ package com.test; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; /** * @author hong_liping * */ public class AtomicIntegerFieldUpdateTest { static AtomicIntegerFieldUpdater aifu=AtomicIntegerFieldUpdater.newUpdater(Person.class, "age"); static class Person{ private String name; public volatile int age; public Person(String name,int age){ this.name=name; this.age=age; } public int getAge(){ return age;