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方法的參數只是比較的這若干個數中的一個數,從而下降了自旋的機率,提升了效率。高併發