Unsafe初探

2023-11-04

Unsafe

Unsafe 是sun.misc.Unsafe下的一个包,通过这个类可以直接使用底层native方法来获取和操作底层的数据,例如获取一个字段在内存中的偏移量,利用偏移量直接获取或修改一个字段的数据等等……

当然这个类正如他的名字一样:不安全的操作。如何理解这个不安全呢?在java的世界里所有的变量都是通过把代码编译成class字节码加载到JVM虚拟机中,通过虚拟机来操作内存中字段的数据,在此过程中,JVM帮程序员做了很多事情,其中大部分是内存的管理。

在JUC(java.util.concurrent)中使用了大量的Unsafe类(多线程、concurrentHashMap、AtomicInteger等等),他可以很方便的使用CAS来确保数据的可见性,同时比正常的Synchroized速度快很多。

使用Unsafe

private Unsafe() {}
//获取示例
public static Unsafe getUnsafe() {
        Class var0 = Reflection.getCallerClass();
        //必须使用BootClassLoader 加载类
        if(!VM.isSystemDomainLoader(var0.getClassLoader())) {
            throw new SecurityException("Unsafe");
        } else {
            return theUnsafe;
        }
    }

因为构造方法私有化,导致不能手动创建实例化,也就是我们平时所说的单例模式。我们可以从Unsafe类中的getUnsafe获取实例,但是返回theUnsafe实例前,会对类加载器进行判断,当不为BootClassLoader时,会抛出错误。

有两种解决方法:
- 当运行你的代码时使用bootclasspath选项并且指定你使用Unsafe类的路径到系统类中。(没有试过,我猜是用BootClassLoader来加载这个类,因为BootClassLoader默认加载rt.jar下的class文件)

java -Xbootclasspath:/usr/jdk1.7.0/jre/lib/rt.jar:
  你的类名
  • 通过反射获取类中的theUnsafe
Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            U = (Unsafe) field.get(null);

当获取Unsafe单例后就可以正常使用了CAS了。传送门:JAVA CAS原理深度分析

package day5;

import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * @author luokai
 * @date 2018/1/15
 */
public class UnsafeTest {


    // Unsafe mechanics
    private static final sun.misc.Unsafe U;
    private static final long SIZE;

    private transient volatile int size;


    static {
        try {
            //系统对Unsafe.getUnsafe 的调用有限制,类加载器必须的限制,但是我们可以使用反射进行获取
            //U = sun.misc.Unsafe.getUnsafe();
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            U = (Unsafe) field.get(null);

            //获取size偏移量
            SIZE = U.objectFieldOffset
                    (UnsafeTest.class.getDeclaredField("size"));


        } catch (Exception e) {
            throw new Error(e);
        }
    }

    public static void main(String[] args) {
        UnsafeTest unsafeTest = new UnsafeTest();
        unsafeTest.size = 2;
        //CAS方法
        System.out.println(U.compareAndSwapInt(unsafeTest, SIZE, 123, -1)); //失败
        System.out.println(U.compareAndSwapInt(unsafeTest, SIZE, unsafeTest.size, -1));
        System.out.println(unsafeTest.size);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unsafe初探 的相关文章

随机推荐

  • 如何利用maven配置mybatis-generator自动生成mapper.xml

    首先配置pom xml文件 新增插件
  • 散点图绘制

    文章目录 1 二维数组的索引 2 npz文件 3 散点图的绘制 在Python数据分析与应用中有一个散点图的例子 做这个例子之前首先要弄清楚两个点 对二维数组进行取数操作 python中的npz文件 1 二维数组的索引 二维数组中的每一个元
  • JS进行sql脚本整理

    JS进行sql脚本整理 在项目增量开发时 会出现开发环境因为集成了新功能或修改了旧功能 导致数据库中数据表字段修改或数据已经更新的情况 这时如果其他环境想要使用新功能 除了更新服务程序外 还需要将开发环境新增的数据整理成sql进行数据同步
  • C++中rand()函数的用法

    C 中rand 函数的用法 1 rand 不需要参数 它会返回一个从0到最大随机数的任意整数 最大随机数的大小通常是固定的一个大整数 2 如果你要产生0 99这100个整数中的一个随机整数 可以表达为 int num rand 100 这样
  • 十进制、二进制、八进制、十六进制之间进行转换的方法_二进制到三十六进制的转换方式...

    进制转换 进制即进位计数制 是人为定义的带进位的计数方法 N进制表示每一位置上的数运算时逢N进一位 如二进制是逢二进一 十进制是逢十进一 十六进制是逢十六进一 以此类推 我们日常生活中使用的进制就是十进制 其他常见进制有二进制 八进制 十六
  • Scala下载及IDEA安装Scala插件(保姆级教程超详细)

    一 Scala的下载与安装 Scala语言可以在Windows Linux Mac OS等系统上编译运行 由于Scala是运行在JVM平台上的 所以安装Scala之前必须配置好JDK环境 JDK版本要求不低于1 5 本博客为基于Window
  • 欧元区PMI数据不佳 关注德拉基讲话

    欧元区PMI数据不佳 关注德拉基讲话 昨日欧元区公布的一系列经济数据表现不佳 由此推动美元指数反弹 给金价带来压力 不过晚间美国公布的就业数 据不佳 再度给金价带来支撑 数据显示 欧元区11月综合PMI初值51 4 创16个月新低 预期52
  • IMX6学习记录(14)-屏幕使用,显示图片、文字

    上面是我的微信和QQ群 欢迎新朋友的加入 1 内核配置 启动板子 能看到一个企鹅在界面上 2 修改文件系统 etc inittab sysinit etc init d rcS console askfirst bin sh tty1 as
  • 华为nova5pro计算机,华为nova5Pro用usb数据线连接电脑的时候连接不上

    华为nova5Pro手机在用这个usb数据线连接电脑的时候连接不上 连接不成功 在电脑下载了华为手机助手 手机上也去华为市场下载了手机助手 按照提示操作依然连不上 看不到华为手机的盘符 打开设备管理器 sea al10那一项有个黄色的感叹号
  • Java Web 集成RTX问题解决

    今天 应项目需求 需要在项目中集成腾讯的RTX 前期根据RTX官方API文档进行测试时 没有任何问题 但是在将代码集成到项目中时 报了一些错误 Init z 现将我的解决过程写下来 希望给遇到同样问题的人提供一些借鉴 1 Init z 类初
  • 解密5G新基建浪潮下的“智慧杆塔”缘何火热

    文章版权所有 未经授权请勿转载或使用 关于智慧杆塔并不算一个新概念或新领域 从早期的智慧路灯 到加载少量城市传感器或电子广告牌的智慧灯杆等 都属于智慧杆塔的早期概念或雏形 但近来笔者通过走访灯杆生产厂商发现 行业终于盼来了爆发的春天 智慧杆
  • odoo 图片预览

    odoo 图片预览 业务需要实现图片上传后进行预览 折腾许久没有成功 最后试着添加图片字段算是基本成功 在 model 中添加字段 odoo 中没有直接的图片 image 字段 但是有一个 binary 二进制字段 image fields
  • 【论文分享】用于多元时间序列的预训练增强的时空图神经网络

    KDD 今天分享的是KDD 2022的一篇论文 Pre training Enhanced Spatial temporal Graph Neural Network for Multivariate Time Series Forecas
  • RFID银行钱箱资产管理系统

    概述 随着经济的发展 金融领域的业务越来越广泛 金融物流安全的问题 显得越来越重要 银行金库每日出入库及配送的物流量越来越大 特别是现金款箱 如果不能保证及时准确的入库 库存控制和出库 将会给银行带来巨大风险 严重加大了银行管理难度 提高了
  • Java之封装、继承和多态(超详细)

    一 封装 封装就是隐藏对象内部的复杂性 只对外公开简单的接口 封装的思想是你只需要知道如何调用接口就行了 不需要去了解内部实现 1 封装的体现 属性的封装 方法的封装 构造函数的封装 单例模式 将类的某些信息隐藏在类的内部 不让外部程序直接
  • Jenkins通过Nexus artifact uploader 上传制品失败排查

    使用Jenkins 插件Nexus artifact uploader 上传 jar zip gzip tar等制品 Jenkins 使用自由风格配置构建时 配置如下 Credentials 为上传Nexus服务器的用户认证信息 需要在Je
  • 计算机网络系统的雷电防护,有关计算机网络系统雷电防护的探讨

    摘要 本文探索与分析了计算机网络系统雷电灾害发生的原因和途径 为雷电灾 害的防护工作提供重要的依据与保障 为减少雷电灾害对计算机网络系统的危害做好理论储备和实施指导 随着现代科学技术的不断发展 计算机网络广泛且迅速延 伸至通信 交通 能源
  • vue3+ts

    安装ts 全局安装typescript npm install g typescript 查看typescript版本 tsc V 1 新建一个ts文件 里面写上 gt function sayHi str return 你好啊 str l
  • 51单片机学习笔记(十一) - LCD1602

    文章目录 一 LCD1602简介 二 LCD1602接口原理图及引脚说明 1 原理图 2 引脚说明 三 LCD1602低层时序 四 LCD1602高层时序 五 一些宏定义 总结 一 LCD1602简介 LCD1602 16x2 显示器显示2
  • Unsafe初探

    Unsafe Unsafe 是sun misc Unsafe下的一个包 通过这个类可以直接使用底层native方法来获取和操作底层的数据 例如获取一个字段在内存中的偏移量 利用偏移量直接获取或修改一个字段的数据等等 当然这个类正如他的名字一