Java提供的原子类是靠 sun 基于 CAS 实现的,CAS 是一种乐观锁。关于乐观锁与悲观锁。html
原子变量类至关于一种泛化的 volatile 变量,可以支持原子的和有条件的读-改-写操做。AtomicInteger 表示一个int类型的值,并提供了 get 和 set 方法,这些 Volatile 类型的int变量在读取和写入上有着相同的内存语义。它还提供了一个原子的 compareAndSet 方法(若是该方法成功执行,那么将实现与读取/写入一个 volatile 变量相同的内存效果),以及原子的添加、递增和递减等方法。AtomicInteger 表面上很是像一个扩展的 Counter 类,但在发生竞争的状况下能提供更高的可伸缩性,由于它直接利用了硬件对并发的支持。算法
AtomicInteger 是一个支持原子操做的 Integer 类,就是保证对 AtomicInteger 类型变量的增长和减小操做是原子性的,不会出现多个线程下的数据不一致问题。若是不使用 AtomicInteger,要实现一个按顺序获取的 ID,就必须在每次获取时进行加锁操做,以免出现并发时获取到一样的 ID 的现象。安全
接下来经过源代码来看 AtomicInteger 具体是如何实现的原子操做。并发
首先看 value 的声明:性能
private volatile int value;
volatile 修饰的 value 变量,保证了变量的可见性。this
incrementAndGet() 方法,下面是具体的代码:spa
public final int incrementAndGet() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return next; } }
经过源码,能够知道,这个方法的作法为先获取到当前的 value 属性值,而后将 value 加 1,赋值给一个局部的 next 变量,然而,这两步都是非线程安全的,可是内部有一个死循环,不断去作 compareAndSet 操做,直到成功为止,也就是修改的根本在 compareAndSet 方法里面,compareAndSet()方法的代码以下:线程
public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); }
compareAndSet()方法调用的compareAndSwapInt()方法的声明以下,是一个native方法。 code
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, intvar5);
compareAndSet 传入的为执行方法时获取到的 value 属性值,next 为加 1 后的值, compareAndSet 所作的为调用 Sun 的 UnSafe 的 compareAndSwapInt 方法来完成,此方法为 native 方法,compareAndSwapInt 基于的是 CPU 的 CAS 指令来实现的。因此基于 CAS 的操做可认为是无阻塞的,一个线程的失败或挂起不会引发其它线程也失败或挂起。而且因为 CAS 操做是 CPU 原语,因此性能比较好。htm
相似的,还有 decrementAndGet() 方法。它和 incrementAndGet() 的区别是将 value 减 1,赋值给next 变量。
AtomicInteger 中还有 getAndIncrement() 和 getAndDecrement() 方法,他们的实现原理和上面的两个方法彻底相同,区别是返回值不一样,前两个方法返回的是改变以后的值,即 next。而这两个方法返回的是改变以前的值,即 current。还有不少的其余方法,就不列举了。
CAS(Compare-And-Swap)算法保证数据操做的原子性。
CAS 算法是硬件对于并发操做共享数据的支持。
CAS 包含了三个操做数:
内存值 V
预估值 A
更新值 B
当且仅当 V == A 时,V 将被赋值为 B,不然循环着不断进行判断 V 与 A 是否相等。