中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中Unsafe如何使用

發布時間:2021-07-02 15:12:36 來源:億速云 閱讀:139 作者:Leah 欄目:編程語言

Java中Unsafe如何使用,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

Unsafe介紹

Unsafe是位于sun.misc包下的一個類,主要提供一些用于執行低級別、不安全操作的方法,如直接訪問系統內存資源、自主管理內存資源等,這些方法在提升Java運行效率、增強Java語言底層資源操作能力方面起到了很大的作用。但由于Unsafe類使得Java語言擁有了類似C語言指針一樣操作內存空間的能力,這無疑也增加了程序發生相關指針問題的風險。在程序中過度、不正確使用Unsafe類會使得程序出錯的概率變大,使得Java這種安全的語言變得不再“安全”,因此對Unsafe的使用一定要慎重。

java.util.concurrent.atomic包下的原子操作類,基本都是使用Unsafe實現的。

Unsafe提供的API大致可分為內存操作、CAS、Class、對象操作、線程、系統信息獲取、內存屏障、數組操作等幾類。

內存相關

Java中Unsafe如何使用

CAS相關

Java中Unsafe如何使用

java.util.concurrent.atomic包中的原子類基本都用的Unsafe

private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long valueOffset; static {   try {     valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));   } catch (Exception ex) { throw new Error(ex); } } public final int getAndSet(int newValue) {   return unsafe.getAndSetInt(this, valueOffset, newValue); }

線程相關

Java中Unsafe如何使用

LockSupport類中有應用unpark,park

public static void park(Object blocker) {   Thread t = Thread.currentThread();   setBlocker(t, blocker);   UNSAFE.park(false, 0L);   setBlocker(t, null); }
public static void unpark(Thread thread) {   if (thread != null)     UNSAFE.unpark(thread); }

Class相關

Java中Unsafe如何使用

對象操作相關

Java中Unsafe如何使用

系統相關

Java中Unsafe如何使用

內存屏障

Java中Unsafe如何使用

loadFence:保證在這個屏障之前的所有讀操作都已經完成。

storeFence:保證在這個屏障之前的所有寫操作都已經完成。

fullFence:保證在這個屏障之前的所有讀寫操作都已經完成。

在java8中 有這個StampedLock類,該類中應用了內存屏障功能。

private static final sun.misc.Unsafe U; static {   try {     U = sun.misc.Unsafe.getUnsafe();   } catch (Exception e) {     throw new Error(e);   } } public boolean validate(long stamp) {   U.loadFence();   return (stamp & SBITS) == (state & SBITS); }
U.loadFence();

Unsafe.java

public final class Unsafe {      private static native void registerNatives();     static {         registerNatives();         sun.reflect.Reflection.registerMethodsToFilter(Unsafe.class, "getUnsafe");     }      private Unsafe() {}      private static final Unsafe theUnsafe = new Unsafe();     // ... }

獲取Unsafe實例

Unsafe類是final且是單例的,并且theUnsafe字段是private;通過如下方法獲取實例

方法1

Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe") ; theUnsafe.setAccessible(true) ; Unsafe unsafe = (Unsafe) theUnsafe.get(null) ;

方法2

private static Unsafe unsafe = null ;      static {     try {         Constructor<Unsafe> cons = Unsafe.class.getDeclaredConstructor() ;         cons.setAccessible(true) ;         unsafe = cons.newInstance() ;     } catch (Exception e) {         e.printStackTrace();     } }

Unsafe簡單應用

int i = 0 ;      public static void main(String[] args) throws Exception {     UnsafeDemo d = new UnsafeDemo() ;     // 獲取Unsafe實例     Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe") ;     theUnsafe.setAccessible(true) ;     Unsafe unsafe = (Unsafe) theUnsafe.get(null) ;     // 獲取類的實例變量     Field f = UnsafeDemo.class.getDeclaredField("i") ;     // 獲取字段相對Java對象的"起始地址"的偏移量     long fieldOffset = unsafe.objectFieldOffset(f) ;     System.out.println(fieldOffset) ;     // 設置值     boolean success = unsafe.compareAndSwapInt(d, fieldOffset, 0, 10) ;     System.out.println(success) ;     System.out.println(d.i) ; }

Unsafe對象操作

private static Unsafe unsafe = null ;      static { try {         Constructor<Unsafe> cons = Unsafe.class.getDeclaredConstructor() ;         cons.setAccessible(true) ;         unsafe = cons.newInstance() ;     } catch (Exception e) {         e.printStackTrace();     } } public static void allocate() {     try {         Person p = (Person)unsafe.allocateInstance(Person.class) ;         p.setId("s001");         System.out.println(p.getValue()) ;         System.out.println(p.getId()) ;     } catch (Exception e) {         e.printStackTrace();     } }

執行結果:

Java中Unsafe如何使用

對象操作2:

private Person p = new Person("1", "張三") ;      public static void main(String[] args) throws Exception {   UnSafeObjectDemo d = new UnSafeObjectDemo() ;   Field field = Unsafe.class.getDeclaredField("theUnsafe") ;     field.setAccessible(true) ;     Unsafe unsafe = (Unsafe) field.get(null) ;     Field f = d.getClass().getDeclaredField("p") ;     long offset = unsafe.objectFieldOffset(f) ;     System.out.println(offset) ;     boolean res = unsafe.compareAndSwapObject(d, offset, d.p, new Person("2", "李四")) ;     System.out.println(res) ;     System.out.println(d.p.getName()) ; }

Java中Unsafe如何使用

Unsafe創建對象

當不知道即將使用的對象有何構造函數,或是不想使用現有對象的構造函數創建對象時,可以通過如下方式:

Constructor<Teacher> cons = (Constructor<Teacher>) ReflectionFactory.getReflectionFactory().newConstructorForSerialization(Teacher.class,                 Object.class.getConstructor()); cons.setAccessible(true); Teacher t = cons.newInstance() ; System.out.println(t) ;

Unsafe簡單實現原子操作類

public class AtomicCount {          private static Unsafe unsafe ;          private int value ;     private static long valueOffset ;          static {         try {             Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe") ;             theUnsafe.setAccessible(true) ;             unsafe = (Unsafe) theUnsafe.get(null) ;                          Field f = AtomicCount.class.getDeclaredField("value") ;             valueOffset = unsafe.objectFieldOffset(f) ;         } catch (Exception e) {             e.printStackTrace();         }     }          public AtomicCount(int value) {         this.value = value ;     }          public final int get() {         return value;     }          public final int getAndIncrement() {         return unsafe.getAndAddInt(this, valueOffset, 1);     }      }

關于Java中Unsafe如何使用問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新乡市| 临清市| 太白县| 周宁县| 彭泽县| 西盟| 正宁县| 当雄县| 巩义市| 武邑县| 丹江口市| 大安市| 北京市| 淅川县| 鲁甸县| 花莲县| 金寨县| 屏南县| 博兴县| 莱州市| 普陀区| 曲沃县| 定州市| 贡觉县| 安多县| 吉水县| 永定县| 江阴市| 秦安县| 新建县| 馆陶县| 五华县| 桦甸市| 廉江市| 涿鹿县| 南丰县| 罗甸县| 固阳县| 扶沟县| 三穗县| 横山县|