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 ...
随机推荐
- Docker从入门到部署项目
Docker概念 Docker是一个开源的应用容器引擎,它是基于Go语言并遵从Apache2.0协议开源.Docker可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流 ...
- 【pytorch】目标检测:一文搞懂如何利用kaggle训练yolov5模型
笔者的运行环境:python3.8+pytorch2.0.1+pycharm+kaggle.yolov5对python和pytorch版本是有要求的,python>=3.8,pytorch> ...
- 论文解读(TAMEPT)《A Two-Stage Framework with Self-Supervised Distillation For Cross-Domain Text Classification》
论文信息 论文标题:A Two-Stage Framework with Self-Supervised Distillation For Cross-Domain Text Classificati ...
- 学习JavaScript的路径
学习JavaScript的路径可以按照以下步骤进行: 了解基本概念:首先学习JavaScript的基本概念,包括变量.数据类型.运算符.数组.对象.循环和条件语句等.可以通过阅读相关的教材.在线课程或 ...
- Node.js vs. Spring Boot:Hello World 性能对决,谁更快一点?
前言: Spring Boot 在 Java 生态中备受欢迎,它是一款基于 Java 构建的轻量级服务端框架,主要用于 Web 服务.Spring Boot 的应用使得创建各类基于 Spring 的企 ...
- Journey -「CQOI 2021」
Day -1 Thu. & Fri. 恰逢学校运动会,于是向班主任申请了不去,然后就在机房坐着.不美好的事情可能就是文化课老师还留了这两天的作业,不过-> 一旦放弃了作业,什么都好说了呢 ...
- Codechef - N Triplets(构造+观察)
题目大意 对于一个正整数N,需要找到三个不同的数字A,B,C,使得三个数当中任意两个数字相乘都是N的约数,另外还要使得A,B,C三个数字乘积是N的整数倍数.最后输出三个数字(如果有多种组合,输出任 ...
- stm32开发笔记
STM32F103C8T6单片机简介 标准库与HAL库区别 寄存器 寄存器众多,需要经常翻阅芯片手册,费时费力: 更大灵活性,可以随心所欲达到自己的目的: 深入理解单片机的运行原理,知其然更知其所以然 ...
- Java21上手体验-分代ZGC和虚拟线程
一.导语 几天前Oracle刚刚发布了Java21, 由于这是最新的LTS版本,引起了大家的关注. 我也第一时间在个人项目中进行了升级体验. 一探究竟,和大家分享. 二.Java21更新内容介绍 官方 ...
- 从链接器的角度详细分析g++报错: (.text+0x24): undefined reference to `main'
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start' ...