1. 程式人生 > >Java執行緒--AtomicReference原子物件

Java執行緒--AtomicReference原子物件

AtomicReference<T>原子物件

AtomicReference<T>作用

是對”物件”T進行原子操作. 

AtomicReference<T>的原始碼剖析

public class AtomicReference<V> implements Serializable {

    private static final Unsafe unsafe = Unsafe.getUnsafe(); //unsafe 實現CAS原子操作

    private volatile V value; //volatile可見性

    public AtomicReference(V var1) {
        this.value = var1;
    }

    /**
     * 讀:volatile變數,在讀時能確保讀到的始終是當前記憶體的最新值
     */
    public final V get() {
        return this.value;
    }

    /**
     * 寫:volatile變數,立即寫回記憶體 並 保證其它cpu內的該值所在的快取行無效(匯流排嗅探技術)
     */
    public final V getAndSet(V var1) {
        return unsafe.getAndSetObject(this, valueOffset, var1); //unsafe 實現原子操作
    }

    //.....省略.....
}

下面附上rt.jar包中的Unsafe類的部分原始碼:主要想表達java.util.concurrent包的靈魂:

/**
* volatile、CAS原理、自旋結構、組合在一起構成了java.util.concurrent包 
*
* volatile:修飾的變數如果是物件或陣列,是指物件或陣列的地址具有可見性,但是陣列或物件內部的成員改變不具備可見性
*
* CAS原理:lock字首指令,執行該cas指令時會鎖住緩衝行
*
*自旋結構:for(;;){ 讀記憶體值; if(cas操作){return;} }
*/ 

package sun.misc;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.ProtectionDomain;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;

/**
* volatile, CAS操作, 自旋結構 組合在一起構成了java.util.concurrent包 
*
* volatile 修飾的變數如果是物件或陣列,其含義是物件或陣列的地址具有可見性,但是陣列或物件內部的成員改變不具備可見性
*
* CAS操作; lock字首指令,執行該cas指令時會鎖住緩衝行
*
*自旋結構; for(;;){ 讀記憶體值; if(cas操作){return;} }
*/

//Unsafe類在%JAVA_HOME%/jre/lib/rt.jar包中

public final class Unsafe
{
  
  private static final Unsafe theUnsafe = new Unsafe();
  public static final int INVALID_FIELD_OFFSET = -1;
  

  /**
  * 自旋結構:for(;;){ 讀記憶體值; if(cas操作compareAndSwapObject){return;} }
  * 引數 paramObject1 cpu舊值
  * 引數 paramLong    偏移量
  * 引數 paramObject2 cpu新值
  */
  public final Object getAndSetObject(Object paramObject1, long paramLong, Object paramObject2)
  {
    Object localObject;
    do
    {
      localObject = getObjectVolatile(paramObject1, paramLong);
    } while (!compareAndSwapObject(paramObject1, paramLong, localObject, paramObject2));
    return localObject;
  }  
  //原子操作:比較並轉換:cpu內舊值paramObject1, 偏移量paramLong, 記憶體當前值paramObject2, cpu內新值paramObject3  
  public final native boolean compareAndSwapObject(Object paramObject1, long paramLong, Object paramObject2, Object paramObject3);
  //原子操作:讀取可見性記憶體值
  public native Object getObjectVolatile(Object paramObject, long paramLong);

  
  
  /**
  * 自旋結構:for(;;){ 讀記憶體值; if(cas操作compareAndSwapInt){return;} }
  * 引數 paramObject1 cpu舊值
  * 引數 paramLong    偏移量
  * 引數 paramInt	  累加
  */
  public final int getAndAddInt(Object paramObject, long paramLong, int paramInt)
  {
    int i;
    do
    {
      i = getIntVolatile(paramObject, paramLong);
    } while (!compareAndSwapInt(paramObject, paramLong, i, i + paramInt));
    return i;
  }
  //原子操作:比較並轉換:cpu內舊值paramObject1, 偏移量paramLong, 記憶體當前值paramObject2, cpu內新值paramObject3
  public final native boolean compareAndSwapInt(Object paramObject, long paramLong, int paramInt1, int paramInt2);
  public native int getIntVolatile(Object paramObject, long paramLong);


  /**
  * 自旋結構:for(;;){ 讀記憶體值; if(cas操作compareAndSwapInt){return;} }
  * 引數 paramObject cpu舊值
  * 引數 paramLong   偏移量
  * 引數 paramInt    cpu新值
  */
  public final int getAndSetInt(Object paramObject, long paramLong, int paramInt)
  {
    int i;
    do
    {
      i = getIntVolatile(paramObject, paramLong);
    } while (!compareAndSwapInt(paramObject, paramLong, i, paramInt));
    return i;
  }

    
  
  public native void unpark(Object paramObject);
  public native void park(boolean paramBoolean, long paramLong);

  public void setMemory(long paramLong1, long paramLong2, byte paramByte)
  {
    setMemory(null, paramLong1, paramLong2, paramByte);
  }
  public void copyMemory(long paramLong1, long paramLong2, long paramLong3)
  {
    copyMemory(null, paramLong1, null, paramLong2, paramLong3);
  }
  public native void setMemory(Object paramObject, long paramLong1, long paramLong2, byte paramByte);
  public native void copyMemory(Object paramObject1, long paramLong1, Object paramObject2, long paramLong2, long paramLong3);


}