unsafe类和varhandle类讲解
Java的Unsafe类是一个非常特殊的类,它提供了一组原始、底层的操作,可以跳过Java的限制,直接操作内存和对象。这些操作可能会破坏Java的安全机制,所以Unsafe类被标记为不安全的。
Unsafe类提供了下列方法:
allocateInstance(Class<T>): 通过反射创建一个实例,不需要调用构造函数。
arrayBaseOffset(Class<T>): 获取数组第一个元素的偏移地址。
arrayIndexScale(Class<T>): 获取数组元素的增量地址。
objectFieldOffset(Field): 获取对象实例字段的偏移地址。
getInt(Object, long): 读取指定内存地址的int值。
putInt(Object, long, int): 设置指定内存地址的int值。
getLong(Object, long): 读取指定内存地址的long值。
putLong(Object, long, long): 设置指定内存地址的long值。
getObject(Object, long): 读取指定内存地址的对象引用。
putObject(Object, long, Object): 设置指定内存地址的对象引用。
这些方法可以用于实现JVM底层的操作,比如手动管理内存、对象序列化、实现基于CAS的并发控制等。但Unsafe类也会带来非常大的安全风险,所以在使用时必须要非常谨慎。
package memory.unsafeTest;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class UnsafeTest {
public static void main(String[] args) throws InstantiationException {
Unsafe unsafe = reflectGetUnsafe();
Message message=new Message(1,"你好");
int anInt = unsafe.getInt(message, 0);
System.out.println(anInt);
long address = unsafe.allocateMemory(4); // 分配4个字节的内存空间
unsafe.putInt(address, 21); // 将值存储到该地址上
System.out.println(unsafe.getInt(address)); // 输出:21
Message demo = (Message) unsafe.allocateInstance(Message.class);
System.out.println(demo.id); // 输出:0
unsafe.freeMemory(address); // 释放内存空间
}
public static Unsafe reflectGetUnsafe(){
try {
Field unsafe = Unsafe.class.getDeclaredField("theUnsafe");
unsafe.setAccessible(true);
return (Unsafe) unsafe.get(null);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
message类:
package memory.unsafeTest;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Message {
public int id;
public String name;
}
pom依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>jdk21Test001</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.86.Final</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.21.9</version>
</dependency>
<!-- proto 与 Json 互转会用到-->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>3.21.9</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.0</version>
</plugin>
</plugins>
</build>
</project>
结果:

VarHandle类是Java 9中引入的一种新的方式,用于在Java中进行原子性和可变性访问。它提供了一种机制,可以在不使用锁的情况下对共享数据进行原子性访问。VarHandle类可以用于访问对象字段,数组元素和静态字段。它提供了一组方法,可以执行原子性读取,写入和更新操作。VarHandle类还提供了一些方法,可以执行非原子性的访问,例如读取和写入操作,这些操作不需要保证线程安全性
package memory.varhandleTest;
import memory.unsafeTest.Message;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
public class VarHandleTest {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
VarHandle xHandle = MethodHandles.lookup().in(Message.class).findVarHandle(Message.class, "id", int.class);
System.out.println(xHandle);
int o = (int)xHandle.get(new Message());
System.out.println(o);
}
}
message类:
package memory.unsafeTest;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Message {
public int id=9;
public String name;
}
输出结果:

搬迁:
var code = "80b25dea-91e5-4922-8239-bd19358058fb"
unsafe类和varhandle类讲解的更多相关文章
- Java并发编程笔记之Unsafe类和LockSupport类源码分析
一.Unsafe类的源码分析 JDK的rt.jar包中的Unsafe类提供了硬件级别的原子操作,Unsafe里面的方法都是native方法,通过使用JNI的方式来访问本地C++实现库. rt.jar ...
- 05-- C++ 类的静态成员详细讲解
C++ 类的静态成员详细讲解 在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用.所以在所有对象中都可以共享它.使用静态成员变量实现多个对象之间的数据共享不 ...
- php面向对象:类的继承实例讲解
什么是类的继承?说白了,我觉得就是提高代码使用效率的.下面我就给大家介绍下继承.大理石平台维修 类的继承概念 子类继承父类的所有成员变量个方法,包括构造方法,当子类被实例化时,php会现在子类中查询构 ...
- 面向对象课后深入学习(C++ 类的静态成员详细讲解)
今天在刚申请了博客,一下午都在写那个随笔,所以说好的来看c++的也放在了最后,下星期就考试了,这个类的静态成员是我不是很懂的,在网上 看到一片很详细的博客考下来回去慢慢看. 在C++中,静态成员是属于 ...
- C++ 类的静态成员详细讲解
在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用.所以在所有对象中都可以共享它.使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节 ...
- C++ 类的静态成员详细讲解(转)
在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用.所以在所有对象中都可以共享它.使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节 ...
- C++ 类的静态成员详细讲解[转]
在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用.所以在所有对象中都可以共享它.使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节 ...
- Socket类 以及 ServerSocket类 讲解
Socket类 套接字是网络连接的端点,套接字使应用可以从网络中读取数据,可以向网络中写入数据.不同计算机上的两个应用程序可以通过连接发送或接收字节流,以此达到相互通信的目的. 为了从一个应用程序向另 ...
- 转:C++ 类的静态成员详细讲解
在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用.所以在所有对象中都可以共享它.使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节 ...
- 【Cocos2d-X开发学习笔记】第12期:动作类CCAction的详细讲解
一般对于游戏中的精灵而言,它们不仅仅是存在于场景中,而且是动态展现的,例如,精灵移动的动态效果.动 画效果.跳动效果.闪烁和旋转动态效果等.每一种效果都可以看成是精灵的一个动作. 一.动作类(CCAc ...
随机推荐
- PXE操作过程 kickstart 无人值守安装
PXE操作过程 分配给同一局域网内新加机器的地址(配置文件) dhcp 分配地址 指明tftp 服务器的地址 tftp服务端开启 udp 配置 默认关闭 安装syslinux 取得 pxelinux. ...
- [glibc2.23源码]阅读源码&调试,找出free_hook-0x13分配失败的原因
0x00 写在前面 发freebuf了:https://www.freebuf.com/articles/endpoint/373258.html 本次阅读源码是本人第一次,算是一个全新的开始.本次看 ...
- 领域驱动设计(DDD):从基础代码探讨高内聚低耦合的演进
大家好,我是付威,一名已在编码第一线奋斗了十余年的程序员.在2019年我初次接触到领域驱动设计(Domain-Driven Design,简称DDD)的概念.在我的探索中,我发现许多有关DDD的教程过 ...
- 使用极速全景图下载大师下载720yun全景图片(一键下载建E、720云全景原图)
VR全景图片下载 软件简介 极速全景图下载大师下载地址: 点击进入下载页面 极速全景图下载大师(VR全景图下载器)软件官网: 点击进入官网 极速全景图下载大师如何下载720yun全景图片 1.首先,在 ...
- 5.2 磁盘CRC32完整性检测
CRC校验技术是用于检测数据传输或存储过程中是否出现了错误的一种方法,校验算法可以通过计算应用与数据的循环冗余校验(CRC)检验值来检测任何数据损坏.通过运用本校验技术我们可以实现对特定内存区域以及磁 ...
- 我在前端写Java SpringBoot项目
前言 玩归玩,闹归闹,别拿 C端 开玩笑! 这里不推荐大家把Node服务作为C端服务,毕竟它是单线程多任务 机制. 这一特性是 Javascript 语言设计之初,就决定了它的使命 - Java &g ...
- Python - 打断点以及如何查看
1.鼠标左键单击代码跟行号中间的地方会出现一个红点,这个就是断点. 2.点击Debug按钮,进入调试模式. 3.当代码运行到断点之前,所有关于变量的代码,都会出现运行的结果. 4.点击Step Int ...
- idea修改默认maven配置
idea修改默认maven配置 方法一 (不推荐) 打开project.default.xml文件,在其中加入如下几行配置. 代码如下 保存修改之后新建一个maven项目查看效果 方法二 新增Proj ...
- 造轮子之集成GraphQL
先简单对比以下GraphQL和WebAPI:GraphQL和Web API(如RESTful API)是用于构建和提供Web服务的不同技术. 数据获取方式: Web API:通常使用RESTful A ...
- Sum of MSLCM 题解
Sum of MSLCM 题目大意 定义 \(\text{MSLCM}(n)\) 为所有满足该数集的 \(\text{lcm}\) 为 \(n\) 的数集中元素个数最多的数集的所有数字的和,现有多次询 ...