Unsafe閱讀筆記:
一、基本描述
-
final類,單例 且 不可集成。
-
實例化類:Unsafe類使用了單例模式,需要通過一個靜態方法getUnsafe()來獲取。但Unsafe類做了限制,如果是普通的調用的話,它會拋出一個SecurityException異常;只有由主類加載器加載的類才能調用這個方法
-
//Java反射實例化Unsafe類 public Unsafe getUnsafe() throws IllegalAccessException { //Field unsafeField = Unsafe.class.getDeclaredFields()[0]; Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); // 將字段的訪問權限設置爲true unsafeField.setAccessible(true); // 因爲theUnsafe字段在Unsafe類中是一個靜態字段,所以通過Field.get()獲取字段值時,可以傳null獲取 Unsafe unsafe = (Unsafe) unsafeField.get(null); return unsafe; }
-
二、詳細介紹
1、先看一張圖,參考裏面有什麼功能,畢竟是工具類嘛
2、然後根據上面的圖來分析工具類的函數
-
普通讀寫:讀寫一個Object對象的field;直接從內存中的一個地址讀寫。
-
public native int getInt(Object var1, long var2);
- 從對象指定偏移地址處讀取一個int
-
public native void putInt(Object var1, long var2, int var4);
- 從IG對象指定偏移地址寫入一個int值
-
public native byte getByte(long var1);
- 從指定內存地址獲取一個byte
-
public native void putByte(long var1, byte var3);
- 在指定內存地址寫入一個byte
-
volatile讀寫:volatile讀寫一個Object的field,volatile可以保證可見性和有序性。
-
public native void putObjectVolatile(Object var1, long var2, Object var4);
- 在對象指定偏移地址寫入一個object,保證有序和可見
-
public native int getIntVolatile(Object var1, long var2);
- 在對象指定偏移地址使用volatile讀取一個int
-
public native void putIntVolatile(Object var1, long var2, int var4);
- 在對象指定偏移地址使用volatile寫入一個int ,保證有序和可見
-
-
有序寫:有序寫一個Object的field,保證有序性不保證可見性,所謂有序性就是保證指令不會被重排。
-
public native void putOrderedObject(Object var1, long var2, Object var4);
- 在對象指定偏移地址寫入一個object對象,保證有序性
-
public native void putOrderedInt(Object var1, long var2, int var4);
- 在對象指定偏移地址寫入一個int, 保證有序性
-
-
直接內存操作:申請內存,重新申請內存。是釋放內存,內存複製。
-
public native long allocateMemory(long var1);
- 分配內存
-
public native long reallocateMemory(long var1, long var3);
- 重新分配內存
-
public native void setMemory(long var1, long var3, byte var5);
- 內存初始化
-
public native void copyMemory(Object var1, long var2, Object var4, long var5, long var7);
- 內存複製
-
public native void freeMemory(long var1);
- 清除內存
-
-
CAS相關:提供int,long和object的CAS操作
public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5);
- (未測試)
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
- (未測試)
public final native boolean compareAndSwapLong(Object var1, long var2, long var4, long var6);
- (未測試)
-
偏移量相關:獲取對象屬性和靜態屬性的偏移量;獲取數據第一個元素的偏移地址(arrayBaseOffset),元素的增量地址(arrayIndexScale)
public native long staticFieldOffset(Field var1);
- 獲取靜態屬性Field在對象中的偏移量,因爲讀寫靜態屬性時必須獲取其偏移量
public native long objectFieldOffset(Field var1);
- 獲取非靜態屬性Field在對象中的偏移量,因爲讀寫必須獲取其偏移量
public native Object staticFieldBase(Field var1);
- 返回靜態屬性Field所在的對象,必須是對象的靜態字段(非靜態會報IllegalArgumentException)
public native int arrayBaseOffset(Class<?> var1);
- 返回數組第一個元素實際地址相對整個數組對象的地址的偏移量
public native int arrayIndexScale(Class<?> var1);
- 用於計算數組中第一個元素所佔用的內存空間
-
線程調度;掛起線程,喚醒線程,monitorEnter,MonitorExit
-
park(boolean var1, long var2);
- 阻塞線程
-
public native void unpark(Object var1);
- 喚醒線程
-
public native void monitorEnter(Object var1);
- 用於方法加鎖(synchronized就是使用的這兩個)
-
public native void monitorExit(Object var1);
- (未測試)
-
public native boolean tryMonitorEnter(Object var1);
- (未測試)
-
-
類加載:定義類,創建對象,定義匿名內部類,確保一個類被加載,判斷是否加載一個類。
-
public native Class<?> defineClass(String var1, byte[] var2, int var3, int var4, ClassLoader var5, ProtectionDomain var6);
- 定義一個類,用於動態地創建類
-
public native Class<?> defineAnonymousClass(Class<?> var1, byte[] var2, Object[] var3);
- 用於動態的創建一個匿名內部類
-
public native Object allocateInstance(Class<?> var1);
- 實例化對象,但是不進行初始化,類初始化和實例初始化都不調用
-
public native boolean shouldBeInitialized(Class<?> var1);
- 用於判斷是否需要初始化一個類(未測試)
-
public native void ensureClassInitialized(Class<?> var1);
- 用於保證已經初始化一個類
-
-
內存屏障:讀屏障、寫屏障、讀寫屏障
public native void loadFence();
- 讀屏障-禁止load重排序
public native void storeFence();
- 寫屏障-禁止store重排序
public native void fullFence();
- 讀寫屏障-禁止load和store重排序
-
系統相關:提供2個系統的api
public native int addressSize();
- 獲得指針的大小(8字節是64位,4字節是32位)
public native int pageSize();
- 返回內存頁的大小,單位是字節。返回值一定是2的多少次冪 單位b
以上文章的內容參考:Java中的Unsafe