一个提供原子操作的一个类,就是保证对AtomicInteger类型变量的增加和减少操作是原子性。而且是在硬件层面实现的原子性。
基于乐观锁CAS(操作原子性)+volatile(变量可见性)+native方法
通过不断重复CAS这一过程来(Compare and Set)实现,简单讲,CAS有三个操作数,内存值V,旧预期值A,要更改的新值B。当且仅当内存值=旧预期值时(此时表示值未被修改),将内存值V修改为新值B。以上的比较更新操作都是原子的,不可被中断,是通过硬件命令保证的原子性。硬件级别的原子性比软件层面控制的原子性的性能要好很多。(这一比较和修改的过程是通过cpu的CMPXCHG指令实现的,它的作用是将指定内存地址的内容与所给的某个值相比,如果相等,则将其内容替换为指令中提供的新值,如果不相等,则更新失败)
1、获取变量值current,因为是被volatile修饰的变量,所以当前获得的是其最新值。
2、对变量值current进行运算
3、将变量current与当前内存中的值进行对比,若不相等,说明变量值在此期间被做过修改,继续1,2,3过程,直至变量current的值与内存值相等,然后将变量值设置为新值。
为什么要通过无限循环的方式?
在此过程中,获取变量值,对变量进行操作的的过程不是原子性,可能在对变量运算的过程中,变量的值已经被修改,所以要一直通过CAS的方式判断其是否被修改。在CAS过程中,比较并设值的过程本身来讲也不是原子性的,但是在硬件层面通过CPU指令控制了CAS的原子性。
ABA问题:因为CAS需要在操作值的时候检查下值有没有发生变化,如果没有发生变化则更新,但是如果一个值原来是A,变成了B,又变成了A,那么使用CAS进行检查时会发现它的值没有发生变化,但是实际上却变化了。通过AtomicStampedReference解决。这个类的compareAndSet方法作用是首先检查当前引用是否等于预期引用,并且当前标志是否等于预期标志,如果全部相等,则以原子方式将该引用和该标志的值设置为给定的更新值。