Java中Unsafe如何使用

Java中Unsafe如何使用,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

10年積累的網(wǎng)站設(shè)計(jì)制作、網(wǎng)站制作經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶(hù)對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶(hù)得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有嵩明免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

Unsafe介紹

Unsafe是位于sun.misc包下的一個(gè)類(lèi),主要提供一些用于執(zhí)行低級(jí)別、不安全操作的方法,如直接訪(fǎng)問(wèn)系統(tǒng)內(nèi)存資源、自主管理內(nèi)存資源等,這些方法在提升Java運(yùn)行效率、增強(qiáng)Java語(yǔ)言底層資源操作能力方面起到了很大的作用。但由于Unsafe類(lèi)使得Java語(yǔ)言擁有了類(lèi)似C語(yǔ)言指針一樣操作內(nèi)存空間的能力,這無(wú)疑也增加了程序發(fā)生相關(guān)指針問(wèn)題的風(fēng)險(xiǎn)。在程序中過(guò)度、不正確使用Unsafe類(lèi)會(huì)使得程序出錯(cuò)的概率變大,使得Java這種安全的語(yǔ)言變得不再“安全”,因此對(duì)Unsafe的使用一定要慎重。

java.util.concurrent.atomic包下的原子操作類(lèi),基本都是使用Unsafe實(shí)現(xiàn)的。

Unsafe提供的API大致可分為內(nèi)存操作、CAS、Class、對(duì)象操作、線(xiàn)程、系統(tǒng)信息獲取、內(nèi)存屏障、數(shù)組操作等幾類(lèi)。

內(nèi)存相關(guān)

Java中Unsafe如何使用

CAS相關(guān)

Java中Unsafe如何使用

java.util.concurrent.atomic包中的原子類(lèi)基本都用的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); }

線(xiàn)程相關(guān)

Java中Unsafe如何使用

LockSupport類(lèi)中有應(yīng)用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相關(guān)

Java中Unsafe如何使用

對(duì)象操作相關(guān)

Java中Unsafe如何使用

系統(tǒng)相關(guān)

Java中Unsafe如何使用

內(nèi)存屏障

Java中Unsafe如何使用

loadFence:保證在這個(gè)屏障之前的所有讀操作都已經(jīng)完成。

storeFence:保證在這個(gè)屏障之前的所有寫(xiě)操作都已經(jīng)完成。

fullFence:保證在這個(gè)屏障之前的所有讀寫(xiě)操作都已經(jīng)完成。

在java8中 有這個(gè)StampedLock類(lèi),該類(lèi)中應(yīng)用了內(nèi)存屏障功能。

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實(shí)例

Unsafe類(lèi)是final且是單例的,并且theUnsafe字段是private;通過(guò)如下方法獲取實(shí)例

方法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簡(jiǎn)單應(yīng)用

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

Unsafe對(duì)象操作

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();     } }

執(zhí)行結(jié)果:

Java中Unsafe如何使用

對(duì)象操作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創(chuàng)建對(duì)象

當(dāng)不知道即將使用的對(duì)象有何構(gòu)造函數(shù),或是不想使用現(xiàn)有對(duì)象的構(gòu)造函數(shù)創(chuàng)建對(duì)象時(shí),可以通過(guò)如下方式:

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簡(jiǎn)單實(shí)現(xiàn)原子操作類(lèi)

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);     }      }

關(guān)于Java中Unsafe如何使用問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

文章名稱(chēng):Java中Unsafe如何使用
轉(zhuǎn)載源于:http://bm7419.com/article20/pcisjo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供、用戶(hù)體驗(yàn)、標(biāo)簽優(yōu)化、電子商務(wù)、靜態(tài)網(wǎng)站、定制網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)