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

Java中的Unsafe工具類使用詳解

 更新時間:2023年12月16日 09:30:31   作者:小晨想好好學習  
這篇文章主要介紹了Java中的Unsafe工具類使用詳解,Unsafe是jdk提供的一個直接訪問操作系統(tǒng)資源的工具類(底層c++實現(xiàn)),它可以直接分配內(nèi)存,內(nèi)存復制,copy,提供cpu級別的CAS樂觀鎖等操作,需要的朋友可以參考下

一、Unsafe是什么?

Unsafe是jdk提供的一個直接訪問操作系統(tǒng)資源的工具類(底層c++實現(xiàn)),它可以直接分配內(nèi)存,內(nèi)存復制,copy,提供cpu級別的CAS樂觀鎖等操作。

Unsafe位于sun.misc包下,jdk中的并發(fā)編程包juc(java.util.concurrent)基本全部靠Unsafe實現(xiàn),由此可見其重要性。

二、Unsafe對象的獲取

查看源碼:

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

結論:

  • Unsafe是餓漢式的單例模式
  • 只允許被引導類加載器(BootstrapClassLoader)加載的類使用,查看源碼可以看到在獲取unsafe對象時會判斷調(diào)用類是否是系統(tǒng)類加載器加載的,所以我們無法在自己的類中直接通過Unsafe.getUnsafe()獲取unsafe對象。所以只能通過反射直接new一個或者將其內(nèi)部靜態(tài)成員變量theUnsafe獲取出來
public static void main(String[] args) throws Exception{
    Class<Unsafe> unsafeClass = Unsafe.class;
    //方法一:通過反射構造一個Unsafe對象
    Constructor<Unsafe> constructor = unsafeClass.getDeclaredConstructor();
    constructor.setAccessible(true);
    Unsafe unsafe1 = constructor.newInstance();
    System.out.println(unsafe1);
    //方法二:獲取內(nèi)部靜態(tài)成員變量
    Field theUnsafe = unsafeClass.getDeclaredField("theUnsafe");
    theUnsafe.setAccessible(true);
    Unsafe unsafe2 = (Unsafe) theUnsafe.get(null);
    System.out.println(unsafe2);
}

三、CAS

CAS譯為Compare And Swap,它是樂觀鎖的一種實現(xiàn)。假設主存值為pre,預期值為expect,想要更新成得值為update,當且僅當主存值pre等預期值expect時,才將pre更新為update。

1、相關方法

在unsafe中,實現(xiàn)CAS算法通過cpu的原子指令cmpxchg實現(xiàn),它對應的方法如下:

在這里插入圖片描述

簡單介紹下它使用的參數(shù):

  • 第一個參數(shù) var1為內(nèi)存中要操作的對象
  • 第二個參數(shù) var2為要操作的值的內(nèi)存地址偏移量
  • 第三個參數(shù) var4為預期值
  • 第四個參數(shù) var5 為想要更新成的值

為了方便理解,舉個栗子。類User有一個成員變量name。我們new了一個對象User后,就知道了它(User對象)在內(nèi)存中的起始值,而員變量name在對象中的位置偏移是固定的。這樣通過這個起始值和這個偏移量就能夠定位到成員變量name在內(nèi)存中的具體位置。

如何得出name在對象User中的偏移量,Unsafe自然也提供了相應的方法:

在這里插入圖片描述

2、demo

import sun.misc.Unsafe;
import java.lang.reflect.*;
public class UnsafeDemo {
    public static void main(String[] args) throws Exception {
        Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
        theUnsafe.setAccessible(true);
        Unsafe unsafe = (Unsafe) theUnsafe.get(null);
        User user = new User("jsbintask");
        long nameOffset = unsafe.objectFieldOffset(User.class.getDeclaredField("name"));
        boolean res1 = unsafe.compareAndSwapObject(user, nameOffset, "jsbintask1", "jsbintask2");
        System.out.println(res1+", 第一次更新后的值:" + user.getName());
        boolean res2 = unsafe.compareAndSwapObject(user, nameOffset, "jsbintask", "jsbintask2");
        System.out.println(res2+", 第二次更新后的值:" + user.getName());
    }
    public static class User {
        private String name;
            public User(String name) {
            this.name = name;
        }
        public String getName() {
            return name;
        }
    }  
}

在這里插入圖片描述

因為內(nèi)存中name的值為"jsbintask",而第一次使用compareAndSwapObject方法預期值為"jsbintask1",這顯然是不相等的,所以第一次更新失敗,返回false。第二次我們傳入了正確的預期值,返回true,更新成功!

四、內(nèi)存分配

Unsafe還給我們提供了直接分配內(nèi)存,釋放內(nèi)存,拷貝內(nèi)存,內(nèi)存設置等方法,值得注意的是,這里的內(nèi)存指的是堆外內(nèi)存!它是不受jvm內(nèi)存模型掌控的,所以使用需要及其小心

在這里插入圖片描述

之后用到的時候再進行補充

五、線程調(diào)度

通過Unsafe還可以直接將某個線程掛起,這和調(diào)用Object.wait()方法作用是一樣的,但是效率確更高!

在這里插入圖片描述

我們熟知的AQS(AbstractQueuedSynchronizer)內(nèi)部掛起線程使用了LockSupport,而LockSupport內(nèi)部依舊使用的是Unsafe:

到此這篇關于Java中的Unsafe工具類使用詳解的文章就介紹到這了,更多相關Unsafe工具類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 使用jdk1.8實現(xiàn)將list根據(jù)指定的值去分組的操作

    使用jdk1.8實現(xiàn)將list根據(jù)指定的值去分組的操作

    這篇文章主要介紹了使用jdk1.8實現(xiàn)將list根據(jù)指定的值去分組的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Java異常處理操作 Throwable、Exception、Error

    Java異常處理操作 Throwable、Exception、Error

    這篇文章主要介紹了Java異常處理操作 Throwable、Exception、Error,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 2022最新Java泛型詳解(360度無死角介紹)

    2022最新Java泛型詳解(360度無死角介紹)

    Java泛型(generics)是JDK5中引入的一個新特性,泛型提供了 編譯時類型安全監(jiān)測機制,該機制允許我們在編譯時檢測到非法的類型數(shù)據(jù)結構,這篇文章主要介紹了java泛型的基本概念及使用詳解,感興趣的朋友跟隨小編一起看看吧
    2022-10-10
  • SpringMVC結合模板模式實現(xiàn)MyBatisPlus傳遞嵌套JSON數(shù)據(jù)

    SpringMVC結合模板模式實現(xiàn)MyBatisPlus傳遞嵌套JSON數(shù)據(jù)

    我們經(jīng)常會遇到需要傳遞對象的場景,有時候,我們需要將一個對象的數(shù)據(jù)傳遞給另一個對象進行處理,但是又不希望直接暴露對象的內(nèi)部結構和實現(xiàn)細節(jié),所以本文給大家介紹了SpringMVC結合模板模式實現(xiàn)MyBatisPlus傳遞嵌套JSON數(shù)據(jù),需要的朋友可以參考下
    2024-03-03
  • springboot之聯(lián)表查詢方式

    springboot之聯(lián)表查詢方式

    這篇文章主要介紹了springboot之聯(lián)表查詢方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Spring Boot 中 MyBatis 與 Spring Data JPA 的優(yōu)缺點對比

    Spring Boot 中 MyBatis 與 Spring 

    這篇文章主要介紹了Spring Boot 中 MyBatis 與 Spring Data JPA 的優(yōu)缺點對比,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2025-05-05
  • SpringBoot實現(xiàn)聯(lián)表查詢的代碼詳解

    SpringBoot實現(xiàn)聯(lián)表查詢的代碼詳解

    這篇文章主要介紹了SpringBoot中如何實現(xiàn)聯(lián)表查詢,文中通過代碼示例和圖文結合的方式講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-05-05
  • java轉(zhuǎn)發(fā)和重定向的區(qū)別

    java轉(zhuǎn)發(fā)和重定向的區(qū)別

    這篇文章主要介紹了java轉(zhuǎn)發(fā)和重定向的區(qū)別,需要的朋友可以參考下
    2014-10-10
  • SpringBoot算法實現(xiàn)數(shù)據(jù)加密傳輸

    SpringBoot算法實現(xiàn)數(shù)據(jù)加密傳輸

    這篇文章主要為大家詳細介紹了SpringBoot算法實現(xiàn)數(shù)據(jù)加密傳輸?shù)南嚓P知識,本文主要是混合加密,前端 SM2 + SM4,后端 Spring Boot + Hutool 解密,希望對大家有所幫助
    2026-03-03
  • Java繼承構造器使用過程解析

    Java繼承構造器使用過程解析

    這篇文章主要介紹了Java繼承構造器使用過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12

最新評論

乐陵市| 上杭县| 旺苍县| 丰台区| 拉孜县| 榆树市| 叙永县| 高雄市| 尤溪县| 深水埗区| 正宁县| 河津市| 永兴县| 宜川县| 唐海县| 南皮县| 南宫市| 曲麻莱县| 肇州县| 法库县| 手机| 霸州市| 三江| 永济市| 牟定县| 荃湾区| 通城县| 西乌珠穆沁旗| 天镇县| 上林县| 梁山县| 江山市| 孝义市| 策勒县| 文登市| 南木林县| 兴宁市| 阿巴嘎旗| 常德市| 华坪县| 扬州市|