Unsafe

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、先看一張圖,參考裏面有什麼功能,畢竟是工具類嘛

img

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

發佈了48 篇原創文章 · 獲贊 17 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章