1. 程式人生 > >Java中原子類的實現

Java中原子類的實現

Java提供的原子類是靠sun基於CAS實現的,CAS是一種樂觀鎖。關於樂觀鎖與悲觀鎖

  原子變數類相當於一種泛化的volatile變數,能夠支援原子的和有條件的讀-改-寫操作。AtomicInteger表示一個int型別的值,並提供了get和set方法,這些Volatile型別的int變數在讀取和寫入上有著相同的記憶體語義。它還提供了一個原子的compareAndSet方法(如果該方法成功執行,那麼將實現與讀取/寫入一個volatile變數相同的記憶體效果),以及原子的新增、遞增和遞減等方法。AtomicInteger表面上非常像一個擴充套件的Counter類,但在發生競爭的情況下能提供更高的可伸縮性,因為它直接利用了硬體對併發的支援。

AtomicInteger的實現

  AtomicInteger 是一個支援原子操作的 Integer 類,就是保證對AtomicInteger型別變數的增加和減少操作是原子性的,不會出現多個執行緒下的資料不一致問題。如果不使用 AtomicInteger,要實現一個按順序獲取的 ID,就必須在每次獲取時進行加鎖操作,以避免出現併發時獲取到同樣的 ID 的現象。

  接下來通過原始碼來看AtomicInteger具體是如何實現的原子操作。

  首先看incrementAndGet() 方法,下面是具體的程式碼:

  通過原始碼,可以知道,這個方法的做法為先獲取到當前的 value 屬性值,然後將 value 加 1,賦值給一個區域性的 next 變數,然而,這兩步都是非執行緒安全的,但是內部有一個死迴圈,不斷去做compareAndSet操作,直到成功為止,也就是修改的根本在compareAndSet方法裡面,compareAndSet()方法的程式碼如下:

  compareAndSet()方法呼叫的compareAndSwapInt()方法的宣告如下,是一個native方法。 

  compareAndSet 傳入的為執行方法時獲取到的 value 屬性值,next 為加 1 後的值, compareAndSet 所做的為呼叫 Sun 的 UnSafe 的 compareAndSwapInt 方法來完成,此方法為 native 方法,compareAndSwapInt 基於的是 CPU 的 CAS 指令來實現的。所以基於 CAS 的操作可認為是無阻塞的,一個執行緒的失敗或掛起不會引起其它執行緒也失敗或掛起。並且由於 CAS 操作是 CPU 原語,所以效能比較好

  類似的,還有 decrementAndGet() 方法。它和 incrementAndGet() 的區別是將 value 減 1,賦值給next 變數。

      AtomicInteger 中還有 getAndIncrement() 和 getAndDecrement() 方法,他們的實現原理和上面的兩個方法完全相同,區別是返回值不同,前兩個方法返回的是改變之後的值,即 next。而這兩個方法返回的是改變之前的值,即 current。還有很多的其他方法,就不列舉了。