Atomic的使用
AtomicInteger
public static void main(String[] args) throws InterruptedException {AtomicInteger sum = new AtomicInteger(0);for (int i = 0; i < 10; i++) {new Thread(new Runnable() {@Overridepublic void run() {for (int j = 0; j < 10000; j++) {//原子自增sum.incrementAndGet();}}}).start();}Thread.sleep(10000);System.out.println("sum:" + sum.get());}

AtomicIntegerArray,原子更新数组
public static void main(String[] args) throws InterruptedException {int[] arr = {1, 2, 3, 4, 5};AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(arr);//把下标为2的值修改为10atomicIntegerArray.set(2, 10);System.out.println("当前下标2的值:" + atomicIntegerArray.get(2));//把下标为0的值加20atomicIntegerArray.getAndAdd(0,20);System.out.println(atomicIntegerArray);}

AtomicReference,原子更新引用类型
public static void main(String[] args) throws InterruptedException {User user1 = new User(1, "haha1");User user2 = new User(2, "haha2");User user3 = new User(3, "haha3");AtomicReference<User> atomicReference = new AtomicReference<>(user1);//把user2赋值给ReferenceatomicReference.compareAndSet(user1, user2);System.out.println("当前Reference:" + atomicReference.get());//这里会设置失败,因为的Reference是user2atomicReference.compareAndSet(user1, user3);System.out.println("当前Reference:" + atomicReference.get());}

LongAdder/DoubleAdder
AtomicLong�是利用了CAS操作来提供并发性和原子性的,它的逻辑是采用自旋的方式不断更新目标值,直到更新成功。
但是,高并发环境下,N个线程同时进行自旋操作,会出现大量失败并不断自旋的情况,此时AtomicLong的自旋会成为瓶颈。
LongAdder引入的初衷——解决高并发环境下AtomicLong
例如AtomicLong中有个内部变量value保存着实际的long值,所有的操作都是针对该变量进行。也就是说,高并发环境下,value变量其实是一个热点,也就是N个线程竞争一个热点。
LongAdder的基本思路就是分散热点,将value值分散到一个数组中,不同线程会命中到数组的不同槽中,各个线程只对自己槽中的那个值进行CAS操作。这样热点就被分散了,冲突的概率就小很多。如果要获取真正的long值,只要将各个槽中的变量值累加返回。
