最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一篇看懂Java中的Unsafe類

 更新時(shí)間:2018年05月24日 09:19:27   作者:Ye_yang  
在閱讀AtomicInteger的源碼時(shí),看到了這個(gè)類:sum.msic.Unsafe,之前從沒見過。所以花了點(diǎn)時(shí)間研究了下,下面這篇文章主要給大家介紹了關(guān)于Java中Unsafe類的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起學(xué)習(xí)學(xué)習(xí)吧

前言

本文主要給大家介紹了關(guān)于Java中Unsafe類的相關(guān)內(nèi)容,分享出來供大家參考學(xué)習(xí),下面話不多說了,來一起看看詳細(xì)的介紹吧

1.Unsafe類介紹

Unsafe類是在sun.misc包下,不屬于Java標(biāo)準(zhǔn)。但是很多Java的基礎(chǔ)類庫,包括一些被廣泛使用的高性能開發(fā)庫都是基于Unsafe類開發(fā)的,比如Netty、Hadoop、Kafka等。

使用Unsafe可用來直接訪問系統(tǒng)內(nèi)存資源并進(jìn)行自主管理,Unsafe類在提升Java運(yùn)行效率,增強(qiáng)Java語言底層操作能力方面起了很大的作用。

Unsafe可認(rèn)為是Java中留下的后門,提供了一些低層次操作,如直接內(nèi)存訪問、線程調(diào)度等。

 官方并不建議使用Unsafe。

下面是使用Unsafe的一些例子。

1.1實(shí)例化私有類

import java.lang.reflect.Field; 
import sun.misc.Unsafe; 
public class UnsafePlayer { 
 public static void main(String[] args) throws Exception { 
 //通過反射實(shí)例化Unsafe 
 Field f = Unsafe.class.getDeclaredField("theUnsafe"); 
 f.setAccessible(true); 
 Unsafe unsafe = (Unsafe) f.get(null); 
 //實(shí)例化Player 
 Player player = (Player) unsafe.allocateInstance(Player.class); 
 player.setName("li lei"); 
 System.out.println(player.getName()); 
 } 
} 
 
class Player{ 
 private String name; 
 private Player(){}
 public String getName() { 
 return name; 
 } 
 public void setName(String name) { 
 this.name = name; 
 } 
}

1.2CAS操作,通過內(nèi)存偏移地址修改變量值

java并發(fā)包中的SynchronousQueue中的TransferStack中使用CAS更新棧頂。

/ Unsafe mechanics
private static final sun.misc.Unsafe UNSAFE;
private static final long headOffset;
static {
 try {
 UNSAFE = sun.misc.Unsafe.getUnsafe();
 Class<?> k = TransferStack.class;
 headOffset = UNSAFE.objectFieldOffset
  (k.getDeclaredField("head"));
 } catch (Exception e) {
 throw new Error(e);
 }
}
//棧頂
volatile SNode head;
//更新棧頂
boolean casHead(SNode h, SNode nh) {
 return h == head &&
 UNSAFE.compareAndSwapObject(this, headOffset, h, nh);
}

1.3直接內(nèi)存訪問

Unsafe的直接內(nèi)存訪問:用Unsafe開辟的內(nèi)存空間不占用Heap空間,當(dāng)然也不具有自動(dòng)內(nèi)存回收功能。做到像C一樣自由利用系統(tǒng)內(nèi)存資源。

2.Unsafe類源碼分析

Unsafe的大部分API都是native的方法,主要包括以下幾類:

1)Class相關(guān)。主要提供Class和它的靜態(tài)字段的操作方法。

2)Object相關(guān)。主要提供Object和它的字段的操作方法。

3)Arrray相關(guān)。主要提供數(shù)組及其中元素的操作方法。

4)并發(fā)相關(guān)。主要提供低級(jí)別同步原語,如CAS、線程調(diào)度、volatile、內(nèi)存屏障等。

5)Memory相關(guān)。提供了直接內(nèi)存訪問方法(繞過Java堆直接操作本地內(nèi)存),可做到像C一樣自由利用系統(tǒng)內(nèi)存資源。

6)系統(tǒng)相關(guān)。主要返回某些低級(jí)別的內(nèi)存信息,如地址大小、內(nèi)存頁大小。

2.1Class相關(guān)

//靜態(tài)屬性的偏移量,用于在對(duì)應(yīng)的Class對(duì)象中讀寫靜態(tài)屬性
public native long staticFieldOffset(Field f);
 
public native Object staticFieldBase(Field f);
//判斷是否需要初始化一個(gè)類
public native boolean shouldBeInitialized(Class<?> c);
//確保類被初始化
public native void ensureClassInitialized(Class<?> c);
//定義一個(gè)類,可用于動(dòng)態(tài)創(chuàng)建類
public native Class<?> defineClass(String name, byte[] b, int off, int len,
     ClassLoader loader,
     ProtectionDomain protectionDomain);
//定義一個(gè)匿名類,可用于動(dòng)態(tài)創(chuàng)建類
public native Class<?> defineAnonymousClass(Class<?> hostClass, byte[] data, Object[] cpPatches);

2.2Object相關(guān)

Java中的基本類型(boolean、byte、char、short、int、long、float、double)及對(duì)象引用類型都有以下方法。

//獲得對(duì)象的字段偏移量 
public native long objectFieldOffset(Field f); 
//獲得給定對(duì)象地址偏移量的int值
public native int getInt(Object o, long offset);
//設(shè)置給定對(duì)象地址偏移量的int值
public native void putInt(Object o, long offset, int x);
//創(chuàng)建對(duì)象,但并不會(huì)調(diào)用其構(gòu)造方法。如果類未被初始化,將初始化類。
public native Object allocateInstance(Class<?> cls)
 throws InstantiationException;

2.3數(shù)組相關(guān)

/**
 * Report the offset of the first element in the storage allocation of a
 * given array class. If {@link #arrayIndexScale} returns a non-zero value
 * for the same class, you may use that scale factor, together with this
 * base offset, to form new offsets to access elements of arrays of the
 * given class.
 *
 * @see #getInt(Object, long)
 * @see #putInt(Object, long, int)
 */
//返回?cái)?shù)組中第一個(gè)元素的偏移地址
public native int arrayBaseOffset(Class<?> arrayClass);
//boolean、byte、short、char、int、long、float、double,及對(duì)象類型均有以下方法
/** The value of {@code arrayBaseOffset(boolean[].class)} */
public static final int ARRAY_BOOLEAN_BASE_OFFSET
 = theUnsafe.arrayBaseOffset(boolean[].class);
 
/**
 * Report the scale factor for addressing elements in the storage
 * allocation of a given array class. However, arrays of "narrow" types
 * will generally not work properly with accessors like {@link
 * #getByte(Object, int)}, so the scale factor for such classes is reported
 * as zero.
 *
 * @see #arrayBaseOffset
 * @see #getInt(Object, long)
 * @see #putInt(Object, long, int)
 */
//返回?cái)?shù)組中每一個(gè)元素占用的大小
public native int arrayIndexScale(Class<?> arrayClass);
 
//boolean、byte、short、char、int、long、float、double,及對(duì)象類型均有以下方法
/** The value of {@code arrayIndexScale(boolean[].class)} */
public static final int ARRAY_BOOLEAN_INDEX_SCALE
 = theUnsafe.arrayIndexScale(boolean[].class);

通過arrayBaseOffset和arrayIndexScale可定位數(shù)組中每個(gè)元素在內(nèi)存中的位置。

2.4并發(fā)相關(guān)

 2.4.1CAS相關(guān)

CAS:CompareAndSwap,內(nèi)存偏移地址offset,預(yù)期值expected,新值x。如果變量在當(dāng)前時(shí)刻的值和預(yù)期值expected相等,嘗試將變量的值更新為x。如果更新成功,返回true;否則,返回false。

//更新變量值為x,如果當(dāng)前值為expected
//o:對(duì)象 offset:偏移量 expected:期望值 x:新值
public final native boolean compareAndSwapObject(Object o, long offset,
       Object expected,
       Object x);
 
public final native boolean compareAndSwapInt(Object o, long offset,
      int expected,
      int x);
 
public final native boolean compareAndSwapLong(Object o, long offset,
      long expected,
      long x);

從Java 8開始,Unsafe中提供了以下方法:

//增加
public final int getAndAddInt(Object o, long offset, int delta) {
 int v;
 do {
 v = getIntVolatile(o, offset);
 } while (!compareAndSwapInt(o, offset, v, v + delta));
 return v;
}
 
public final long getAndAddLong(Object o, long offset, long delta) {
 long v;
 do {
 v = getLongVolatile(o, offset);
 } while (!compareAndSwapLong(o, offset, v, v + delta));
 return v;
}
//設(shè)置
public final int getAndSetInt(Object o, long offset, int newValue) {
 int v;
 do {
 v = getIntVolatile(o, offset);
 } while (!compareAndSwapInt(o, offset, v, newValue));
 return v;
}
 
public final long getAndSetLong(Object o, long offset, long newValue) {
 long v;
 do {
 v = getLongVolatile(o, offset);
 } while (!compareAndSwapLong(o, offset, v, newValue));
 return v;
}
 
public final Object getAndSetObject(Object o, long offset, Object newValue) {
 Object v;
 do {
 v = getObjectVolatile(o, offset);
 } while (!compareAndSwapObject(o, offset, v, newValue));
 return v;

2.4.2線程調(diào)度相關(guān)

//取消阻塞線程
public native void unpark(Object thread);
//阻塞線程
public native void park(boolean isAbsolute, long time);
//獲得對(duì)象鎖
public native void monitorEnter(Object o);
//釋放對(duì)象鎖
public native void monitorExit(Object o);
//嘗試獲取對(duì)象鎖,返回true或false表示是否獲取成功
public native boolean tryMonitorEnter(Object o);

2.4.3volatile相關(guān)讀寫

Java中的基本類型(boolean、byte、char、short、int、long、float、double)及對(duì)象引用類型都有以下方法。

//從對(duì)象的指定偏移量處獲取變量的引用,使用volatile的加載語義
//相當(dāng)于getObject(Object, long)的volatile版本
public native Object getObjectVolatile(Object o, long offset);
 
//存儲(chǔ)變量的引用到對(duì)象的指定的偏移量處,使用volatile的存儲(chǔ)語義
//相當(dāng)于putObject(Object, long, Object)的volatile版本
public native void putObjectVolatile(Object o, long offset, Object x);
/**
 * Version of {@link #putObjectVolatile(Object, long, Object)}
 * that does not guarantee immediate visibility of the store to
 * other threads. This method is generally only useful if the
 * underlying field is a Java volatile (or if an array cell, one
 * that is otherwise only accessed using volatile accesses).
 */
public native void putOrderedObject(Object o, long offset, Object x);
 
/** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)} */
public native void putOrderedInt(Object o, long offset, int x);
 
/** Ordered/Lazy version of {@link #putLongVolatile(Object, long, long)} */
public native void putOrderedLong(Object o, long offset, long x);

2.4.4內(nèi)存屏障相關(guān)

Java 8引入 ,用于定義內(nèi)存屏障,避免代碼重排序。

//內(nèi)存屏障,禁止load操作重排序,即屏障前的load操作不能被重排序到屏障后,屏障后的load操作不能被重排序到屏障前
public native void loadFence();
//內(nèi)存屏障,禁止store操作重排序,即屏障前的store操作不能被重排序到屏障后,屏障后的store操作不能被重排序到屏障前
public native void storeFence();
//內(nèi)存屏障,禁止load、store操作重排序
public native void fullFence();

2.5直接內(nèi)存訪問(非堆內(nèi)存)

allocateMemory所分配的內(nèi)存需要手動(dòng)free(不被GC回收)

//(boolean、byte、char、short、int、long、float、double)都有以下get、put兩個(gè)方法。 
//獲得給定地址上的int值
public native int getInt(long address);
//設(shè)置給定地址上的int值
public native void putInt(long address, int x);
//獲得本地指針
public native long getAddress(long address);
//存儲(chǔ)本地指針到給定的內(nèi)存地址
public native void putAddress(long address, long x);
 
//分配內(nèi)存
public native long allocateMemory(long bytes);
//重新分配內(nèi)存
public native long reallocateMemory(long address, long bytes);
//初始化內(nèi)存內(nèi)容
public native void setMemory(Object o, long offset, long bytes, byte value);
//初始化內(nèi)存內(nèi)容
public void setMemory(long address, long bytes, byte value) {
 setMemory(null, address, bytes, value);
}
//內(nèi)存內(nèi)容拷貝
public native void copyMemory(Object srcBase, long srcOffset,
    Object destBase, long destOffset,
    long bytes);
//內(nèi)存內(nèi)容拷貝
public void copyMemory(long srcAddress, long destAddress, long bytes) {
 copyMemory(null, srcAddress, null, destAddress, bytes);
}
//釋放內(nèi)存
public native void freeMemory(long address);

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

//返回指針的大小。返回值為4或8。
public native int addressSize();
 
/** The value of {@code addressSize()} */
public static final int ADDRESS_SIZE = theUnsafe.addressSize();
 
//內(nèi)存頁的大小。
public native int pageSize();

3.參考資料

http://m.fzitv.net/article/140709.htm 說一說Java中的Unsafe類

http://m.fzitv.net/article/140721.htm java魔法類:sun.misc.Unsafe

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • java 教你如何給你的頭像添加一個(gè)好看的國旗

    java 教你如何給你的頭像添加一個(gè)好看的國旗

    這篇文章主要介紹了java 教你如何給你的頭像添加一個(gè)好看的國旗,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • JAVA不使用線程池來處理的異步的方法詳解

    JAVA不使用線程池來處理的異步的方法詳解

    這篇文章主要介紹了JAVA不使用線程池來處理的異步的方法,在這個(gè)示例中,asyncTask方法創(chuàng)建了一個(gè)新的線程來執(zhí)行異步任務(wù),這個(gè)新線程會(huì)立即開始執(zhí)行,而主線程則會(huì)繼續(xù)執(zhí)行后續(xù)的代碼,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • SpringSecurity 手機(jī)號(hào)登錄功能實(shí)現(xiàn)

    SpringSecurity 手機(jī)號(hào)登錄功能實(shí)現(xiàn)

    這篇文章主要介紹了SpringSecurity 手機(jī)號(hào)登錄功能實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2023-12-12
  • Java經(jīng)典排序算法之歸并排序?qū)崿F(xiàn)代碼

    Java經(jīng)典排序算法之歸并排序?qū)崿F(xiàn)代碼

    這篇文章主要介紹了Java經(jīng)典排序算法之歸并排序?qū)崿F(xiàn)代碼,歸并排序是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法的一個(gè)非常典型的應(yīng)用,將已有序的子序列合并,得到完全有序的序列,需要的朋友可以參考下
    2023-10-10
  • SpringBoot整合SpringSession實(shí)現(xiàn)分布式登錄詳情

    SpringBoot整合SpringSession實(shí)現(xiàn)分布式登錄詳情

    這篇文章主要介紹了SpringBoot整合SpringSession實(shí)現(xiàn)分布式登錄詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-08-08
  • 你會(huì)用Java代碼模擬高并發(fā)嗎

    你會(huì)用Java代碼模擬高并發(fā)嗎

    這篇文章主要介紹了你會(huì)用Java代碼模擬高并發(fā)嗎,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • SSH框架網(wǎng)上商城項(xiàng)目第16戰(zhàn)之Hibernate二級(jí)緩存處理首頁熱門顯示

    SSH框架網(wǎng)上商城項(xiàng)目第16戰(zhàn)之Hibernate二級(jí)緩存處理首頁熱門顯示

    這篇文章主要介紹了SSH框架網(wǎng)上商城項(xiàng)目第16戰(zhàn)之Hibernate的二級(jí)緩存處理首頁的熱門顯示,感興趣的小伙伴們可以參考一下
    2016-06-06
  • Java錯(cuò)誤問題:找不到或無法加載主類的解決

    Java錯(cuò)誤問題:找不到或無法加載主類的解決

    這篇文章主要介紹了Java錯(cuò)誤問題:找不到或無法加載主類的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Mybatis環(huán)境搭建及文件配置過程解析

    Mybatis環(huán)境搭建及文件配置過程解析

    這篇文章主要介紹了Mybatis環(huán)境搭建及文件配置過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 為什么阿里要慎重使用ArrayList中的subList方法

    為什么阿里要慎重使用ArrayList中的subList方法

    這篇文章主要介紹了為什么要慎重使用ArrayList中的subList方法,subList是List接口中定義的一個(gè)方法,該方法主要用于返回一個(gè)集合中的一段、可以理解為截取一個(gè)集合中的部分元素,他的返回值也是一個(gè)List。,需要的朋友可以參考下
    2019-06-06

最新評(píng)論

万安县| 通许县| 湖北省| 虞城县| 和林格尔县| 托克逊县| 武山县| 黔西县| 枣阳市| 和静县| 长宁县| 清水河县| 丹凤县| 黄石市| 德阳市| 和龙市| 盐亭县| 会昌县| 库伦旗| 岳阳市| 叙永县| 定安县| 津市市| 怀柔区| 克东县| 彭阳县| 全州县| 遵化市| 兴山县| 日照市| 循化| 扬中市| 永春县| 文山县| 衡山县| 长春市| 阿坝县| 加查县| 永年县| 彰化市| 乌鲁木齐县|