CAS-CompareAndSet,是JDK原子变量类AtomicInteger、AtomicLong、AtomicInteger、AtomicBoolean、AtomicReference等实现的基础,例如对于一个共享变量int,就算是简单的自增操做也不是原子性的,多线程同时自增,可能会致使变量的值比预期结果小。可是可使用AtomicInteger的incrementAndGet() 方法操做变量,这样结果和预期值同样。跟传统的加锁不一样,getAndDecrement()方法并无给代码加锁。代码相似于:算法
public final int incrementAndGet() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return next; } }
底层经过sun.misc.Unsafe的本地方法compareAndSwapInt实现,这个方法是原子的。多线程
synchronized是阻塞的,CAS更新是非阻塞的,只是会重试,不会有线程上下文切换开销,对于大部分比较简单的操做,不管是在低并发仍是高并发状况下,这种乐观非阻塞方式的性能都要远高于悲观阻塞式方式。并发
compareAndSet(V expectedReference, V newReference, int expectedStamp, int newStamp)
方法,只有值和时间戳都相等的时候才进行原子更新,每次更新都把当前时间修改进原子变量。JAVA8新增了LongAdder、DoubleAdder对原子变量进行进一步优化,主要是利用了分段CAS的机制,若是不用LongAdder,用AtomicLong的话,在高并发状况下,会产生一直自旋,致使效率不高。他将一个数分红若干个数,CompareAndSet方法的参数只是比较的这若干个数中的一个数,从而下降了自旋的几率,提升了效率。高并发