日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Java中Unsafe使用詳解

Unsafe介紹

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

創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比潼關(guān)網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式潼關(guān)網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋潼關(guān)地區(qū)。費(fèi)用合理售后完善,十載實(shí)體公司更值得信賴。

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

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

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

CAS相關(guān)

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

 
 
 
 
  1. private static final Unsafe unsafe = Unsafe.getUnsafe();
  2. private static final long valueOffset;
  3. static {
  4.   try {
  5.     valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));
  6.   } catch (Exception ex) { throw new Error(ex); }
  7. }
  8. public final int getAndSet(int newValue) {
  9.   return unsafe.getAndSetInt(this, valueOffset, newValue);
  10. }

線程相關(guān)

LockSupport類中有應(yīng)用unpark,park

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

Class相關(guān)

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

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

內(nèi)存屏障

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

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

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

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

 
 
 
 
  1. private static final sun.misc.Unsafe U;
  2. static {
  3.   try {
  4.     U = sun.misc.Unsafe.getUnsafe();
  5.   } catch (Exception e) {
  6.     throw new Error(e);
  7.   }
  8. }
  9. public boolean validate(long stamp) {
  10.   U.loadFence();
  11.   return (stamp & SBITS) == (state & SBITS);
  12. }
 
 
 
 
  1. U.loadFence();

Unsafe.java

 
 
 
 
  1. public final class Unsafe {
  2.     private static native void registerNatives();
  3.     static {
  4.         registerNatives();
  5.         sun.reflect.Reflection.registerMethodsToFilter(Unsafe.class, "getUnsafe");
  6.     }
  7.     private Unsafe() {}
  8.     private static final Unsafe theUnsafe = new Unsafe();
  9.     // ...
  10. }

獲取Unsafe實(shí)例

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

方法1

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

方法2

 
 
 
 
  1. private static Unsafe unsafe = null ;
  2.     
  3. static {
  4.     try {
  5.         Constructor cons = Unsafe.class.getDeclaredConstructor() ;
  6.         cons.setAccessible(true) ;
  7.         unsafe = cons.newInstance() ;
  8.     } catch (Exception e) {
  9.         e.printStackTrace();
  10.     }
  11. }

Unsafe簡單應(yīng)用

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

Unsafe對(duì)象操作

 
 
 
 
  1. private static Unsafe unsafe = null ;
  2.     
  3. static {
  4. try {
  5.         Constructor cons = Unsafe.class.getDeclaredConstructor() ;
  6.         cons.setAccessible(true) ;
  7.         unsafe = cons.newInstance() ;
  8.     } catch (Exception e) {
  9.         e.printStackTrace();
  10.     }
  11. }
  12. public static void allocate() {
  13.     try {
  14.         Person p = (Person)unsafe.allocateInstance(Person.class) ;
  15.         p.setId("s001");
  16.         System.out.println(p.getValue()) ;
  17.         System.out.println(p.getId()) ;
  18.     } catch (Exception e) {
  19.         e.printStackTrace();
  20.     }
  21. }

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

對(duì)象操作2:

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

Unsafe創(chuàng)建對(duì)象

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

 
 
 
 
  1. Constructor cons = (Constructor) ReflectionFactory.getReflectionFactory().newConstructorForSerialization(Teacher.class,
  2.                 Object.class.getConstructor());
  3. cons.setAccessible(true);
  4. Teacher t = cons.newInstance() ;
  5. System.out.println(t) ;

Unsafe簡單實(shí)現(xiàn)原子操作類

 
 
 
 
  1. public class AtomicCount {
  2.     
  3.     private static Unsafe unsafe ;
  4.     
  5.     private int value ;
  6.     private static long valueOffset ;
  7.     
  8.     static {
  9.         try {
  10.             Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe") ;
  11.             theUnsafe.setAccessible(true) ;
  12.             unsafe = (Unsafe) theUnsafe.get(null) ;
  13.             
  14.             Field f = AtomicCount.class.getDeclaredField("value") ;
  15.             valueOffset = unsafe.objectFieldOffset(f) ;
  16.         } catch (Exception e) {
  17.             e.printStackTrace();
  18.         }
  19.     }
  20.     
  21.     public AtomicCount(int value) {
  22.         this.value = value ;
  23.     }
  24.     
  25.     public final int get() {
  26.         return value;
  27.     }
  28.     
  29.     public final int getAndIncrement() {
  30.         return unsafe.getAndAddInt(this, valueOffset, 1);
  31.     }
  32.     
  33. }

完畢?。?!


文章標(biāo)題:Java中Unsafe使用詳解
網(wǎng)站路徑:http://www.dlmjj.cn/article/dpjgijh.html