AtomicInteger能夠看作Integer類的原子操做工具類。在java.util.concurrent.atomic包下,在一些使用場合下能夠取代加鎖操做提升併發性。接下來就從幾個方面來介紹:java
1.原子性和CAS。
編程
2.CPU底層實現原理。數組
3.atomic包介紹。安全
4.源碼分析。數據結構
原子性和CAS併發
原子性就是指某一個操做是不可拆分的,是一個總體必需要一次性所有執行完成要麼就不執行。app
CAS是Compare And Swap(比較並交換)。意思是當你要更新某個值的時候先要檢查這個變量的當前值是否是改變了,若是改變了就不能更新,沒改變就能夠更新。ide
首先,CPU 會將內存中將要被更改的數據與指望的值作比較。而後,當這兩個值相等時,CPU 纔會將內存中的數值替換爲新的值。不然便不作操做。最後,CPU 會將舊的數值返回。這一系列的操做是原子的。它們雖然看似複雜,但倒是 Java 5 併發機制優於原有鎖機制的根本。簡單來講,CAS 的含義是「我認爲原有的值應該是什麼,若是是,則將原有的值更新爲新值,不然不作修改,並告訴我原來的值是多少。高併發
atomic包介紹工具
類的小工具包,支持在單個變量上解除鎖的線程安全編程。此包中的類可將 volatile 值、字段和數組元素的概念擴展到那些也提供原子條件更新操做的類,其形式以下:
boolean compareAndSet(expectedValue, updateValue);
若是此方法(在不一樣的類間參數類型也不一樣)當前保持 expectedValue,則以原子方式將變量設置爲 updateValue,並在成功時報告 true。此包中的類還包含獲取並沒有條件設置值的方法,以及如下描述的較弱條件的原子更新操做 weakCompareAndSet。
原子訪問和更新的內存效果通常遵循如下可變規則:
設計原子類主要用做各類構造塊,用於實現非阻塞數據結構和相關的基礎結構類。compareAndSet 方法不是鎖的常規替換方法。僅當對象的重要更新限定於單個 變量時才應用它。原子類不是 java.lang.Integer 和相關類的通用替換方法。它們不 定義諸如 hashCode 和 compareTo 之類的方法。
源碼舉例分析
AtomicInteger繼承結構:
------java.util.concurrent.atomic.AtomicInteger
還實現了java.io.Serializable以便序列化使用,而後是字段的定義和初始化:
Unsafe裏面定義了許多Native方法,經過JNI調用。value就是AtomicInteger表明的值,這裏用volatile修飾用以保證value的可見性。
//源碼 setup to use Unsafe.compareAndSwapInt for updates private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long valueOffset; static { try { valueOffset = unsafe.objectFieldOffset (AtomicInteger.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } private volatile int value;
AtomicInteger大概實現了20個左右的public方法,下面舉幾個有表明性的來分析:
1.get方法是用來獲取當前最新的value。方法用final修飾是爲了更進一步的保證線程安全。
/** * Gets the current value. * * @return the current value */ public final int get() { return value; }
2.set方法是把value更新爲一個新值。也是用final修飾。
/** * Sets to the given value. * * @param newValue the new value */ public final void set(int newValue) { value = newValue; }
3.lazySet方法和set方法不一樣之處在於能夠延時設置,就是在最後才設定新值。
/** * Eventually sets to the given value. * * @param newValue the new value * @since 1.6 */ public final void lazySet(int newValue) { unsafe.putOrderedInt(this, valueOffset, newValue); }
4.getAndSet方法是把新值設置爲當前值而後返回舊值。
/** * Atomically sets to the given value and returns the old value. * * @param newValue the new value * @return the previous value */ public final int getAndSet(int newValue) { return unsafe.getAndSetInt(this, valueOffset, newValue); }
5.compareAndSet方法是首先比較當前值與指望值,相同才更新到新值。若是更新成功則返回true,不然返回false。
/** * Atomically sets the value to the given updated value * if the current value {@code ==} the expected value. * * @param expect the expected value * @param update the new value * @return {@code true} if successful. False return indicates that * the actual value was not equal to the expected value. */ public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); }
6.getAndIncrement方法是原子的把原值加一而且返回舊值。getAndDecrement相似。
/** * Atomically increments by one the current value. * * @return the previous value */ public final int getAndIncrement() { return unsafe.getAndAddInt(this, valueOffset, 1); }
7.getAndAdd方法是把原值加上某個值,並返回之前的值。
/** * Atomically adds the given value to the current value. * * @param delta the value to add * @return the previous value */ public final int getAndAdd(int delta) { return unsafe.getAndAddInt(this, valueOffset, delta); }
8.incrementAndGet方法是把原值加一後返回新值。decrementAndGet相似。
/** * Atomically increments by one the current value. * * @return the updated value */ public final int incrementAndGet() { return unsafe.getAndAddInt(this, valueOffset, 1) + 1; }
9.getAndUpdate方法是根據一個定義的操做符來把當前值當第一個參數,傳入的參數當作第二個參數更新value,返回舊值。updateAndGet是返回新值。 使用自旋的方式,調用了compareAndSet方法,只有返回了true才結束。
/** * Atomically updates the current value with the results of * applying the given function, returning the previous value. The * function should be side-effect-free, since it may be re-applied * when attempted updates fail due to contention among threads. * * @param updateFunction a side-effect-free function * @return the previous value * @since 1.8 */ public final int getAndUpdate(IntUnaryOperator updateFunction) { int prev, next; do { prev = get(); next = updateFunction.applyAsInt(prev); } while (!compareAndSet(prev, next)); return prev; }
以上這些方法都是原子操做。