您好,登錄后才能下訂單哦!
這篇文章主要介紹“Java原子操作類源碼分析”,在日常操作中,相信很多人在Java原子操作類源碼分析問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java原子操作類源碼分析”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
我們先來看一下部分源碼:
public class AtomicLong extends Number implements java.io.Serializable { private static final long serialVersionUID = 1927816293512124184L; //1.獲取Unsafe類實例 private static final Unsafe unsafe = Unsafe.getUnsafe(); //2.存放value的偏移量 private static final long valueOffset; static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8(); //3.用于判斷是否支持Long類型無鎖CAS private static native boolean VMSupportsCS8(); static { try { //4.獲取value在AtomicLong中的偏移量 valueOffset = unsafe.objectFieldOffset (AtomicLong.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } } //5.實際變量值 private volatile long value; /** * Creates a new AtomicLong with the given initial value. * * @param initialValue the initial value */ public AtomicLong(long initialValue) { value = initialValue; } ············省略部分代碼············· }
上面代碼中,代碼1處通過Unsafe.getUnsafe()獲取到Unsafe類的實例(因為AtomicLong類是在rt.jar包下面的,AtomicLong類就是通過Bootstarp類加載器進行加載的)。代碼5處,value被聲明為volatile類型,保證內存的可見性。通過代碼2,4獲取value變量在AtomicLong類中的偏移量。
接下來介紹一下AtomicLong中的主要函數:
遞增和遞減代碼
//調用unsafe方法,設置value=value+1后,返回原始的值 public final long getAndIncrement() { return unsafe.getAndAddLong(this, valueOffset, 1L); } //調用unsafe方法,設置value=value-1后,返回原始的值 public final long getAndDecrement() { return unsafe.getAndAddLong(this, valueOffset, -1L); } //調用unsafe方法,設置value=value+1后,返回遞增后的值 public final long incrementAndGet() { return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L; } //調用unsafe方法,設置value=value-1后,返回遞減后的值 public final long decrementAndGet() { return unsafe.getAndAddLong(this, valueOffset, -1L) - 1L; }
上面的四個函數內部都是通過調用Unsafe的getAndAddLong方法來實現操作,這個函數是個原子性操作,這里第一個參數是AtomicLong實例的引用的,第二個參數是value變量在AtomicLong的偏移值,第三個參數是要設置的第二個變量的值。
其中getAndIncrement()方法在JDK7中實現邏輯為:
public final long getAndIncrement() { while(true) { long current = get(); long next = current + 1; if (compareAndSet(current, next)) return current; } }
如上代碼中,每個線程是先拿到變量的當前值(由于value是volatile變量,所以這是獲取的最新值),然后在工作內存中對其進行增1操作,而后使用CAS修改變量的值,如果設置失敗,則循環繼續嘗試,直到設置成功。
JDK8中的邏輯為:
public final long getAndIncrement() { retrturn unsafe.getAndAddLong(this, valueOffset, 1L); }
其中JDK8中的unsafe.getAndAddLong的代碼為:
public final long getAndAddLong(Object var1, long var2, long var4) { long var6; do { var6 = this.getLongVolatile(var1, var2); } while(!this.compareAndSwapLong(var1, var2, var6, var6 + var4)); return var6; }
從中可以看到,JDK7中的AtomicLong中循環邏輯已經被JDK8中的原子操作類Unsafe內置了。
boolean compareAndSet(long expect,long update)
public final boolean compareAndSet(long expect,long update) { return unsafe.compareAndSwapLong(this, valueOffset, expect, update); }
函數在內部調用了unsafe.compareAndSwapLong方法。如果原子變量中的value值等于expect,則使用update值更新該值并返回true,否則返回false。
到此,關于“Java原子操作類源碼分析”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。