AtomicInteger&无锁对象引用:AtomicReference
AtomicInteger介绍
AtomicInteger是一个提供原子操作的Integer类,通过线程安全的方式操作加减。
AtomicInteger使用场景
AtomicInteger提供原子操作来进行Integer的使用,因此十分适合高并发情况下的使用。
1.作为多个线程同时使用的原子计数器。
2.在比较和交换操作中实现非阻塞算法。
AtomicInteger作为原子计数器
要将其用作计数器,AtomicInteger类提供了一些方法来原子地执行加减运算。
1 | addAndGet():以原子方式将给定值添加到当前值,并在添加后返回新值。 |
AtomicInteger源码部分讲解
1 | public class AtomicInteger extends Number implements java.io.Serializable { |
以上为AtomicInteger中的部分源码,在这里说下其中的value,这里value使用了volatile关键字,volatile在这里可以做到的作用是使得多个线程可以共享变量,但是问题在于使用volatile将使得VM优化失去作用,导致效率较低,所以要在必要的时候使用,因此AtomicInteger类不要随意使用,要在使用场景下使用。
AtomicInteger的创建、塞值、取值
通过调用构造函数,可以直接创建AtomicInteger。 AtomicInteger提供了两种方法来获取和设置其实例的值。
1 | //Initial value is 0 |
AtomicInteger使用总结
AtomicInteger是在使用非阻塞算法实现并发控制,在一些高并发程序中非常适合,但并不能每一种场景都适合,不同场景要使用使用不同的数值类。
AtomicReference
1、使用场景:
解决并发修改多个属性
说到CAS理论,在java中我们第一个就想到了atomic类,一般常见的有AtomicInteger、AtomicBoolean等java.util.concurrent包下面的类,但是这个只能并发修改一个属性,如果我需要对多个属性同时进行并发修改,并且保证原子性呢?
AtomicReference和AtomicInteger非常类似,不同之处就在于AtomicInteger是对整数的封装,而AtomicReference则对应普通的对象引用,是操控多个属性的原子性的并发类。
业务场景:序列需要自增并且时间需要更新成最新的时间戳
2.简单介绍:
AtomicReference类提供了一个可以原子读写的对象引用变量。 原子意味着尝试更改相同AtomicReference的多个线程(例如,使用比较和交换操作)不会使AtomicReference最终达到不一致的状态。
3、实现原理:
1 | private static final Unsafe unsafe = Unsafe.getUnsafe(); |
AtomicReference的源码比较简单。它是通过”volatile”和”Unsafe提供的CAS函数实现”原子操作。
(01) value是volatile类型。这保证了:当某线程修改value的值时,其他线程看到的value值都是最新的value值,即修改之后的volatile的值。
(02) 通过CAS设置value。这保证了:当某线程池通过CAS函数(如compareAndSet函数)设置value时,它的操作是原子的,即线程在操作value时不会被中断。