当前位置: 首页 > article >正文

unsafe类和varhandle类讲解

Java的Unsafe类是一个非常特殊的类,它提供了一组原始、底层的操作,可以跳过Java的限制,直接操作内存和对象。这些操作可能会破坏Java的安全机制,所以Unsafe类被标记为不安全的。

Unsafe类提供了下列方法:

  1. allocateInstance(Class<T>): 通过反射创建一个实例,不需要调用构造函数。

  2. arrayBaseOffset(Class<T>): 获取数组第一个元素的偏移地址。

  3. arrayIndexScale(Class<T>): 获取数组元素的增量地址。

  4. objectFieldOffset(Field): 获取对象实例字段的偏移地址。

  5. getInt(Object, long): 读取指定内存地址的int值。

  6. putInt(Object, long, int): 设置指定内存地址的int值。

  7. getLong(Object, long): 读取指定内存地址的long值。

  8. putLong(Object, long, long): 设置指定内存地址的long值。

  9. getObject(Object, long): 读取指定内存地址的对象引用。

  10. 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;
}

输出结果:


http://www.kler.cn/a/159585.html

相关文章:

  • git命令提交项目
  • 企业如何提高招聘能力?
  • Python入门(4)--流程控制(下)
  • CSS:怎么把网站都变成灰色
  • 自动化工具 Gulp
  • 深入探索:Scrapy深度爬取策略与实践
  • 查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
  • 1 NLP分类之:FastText
  • 同旺科技 USB TO RS-485 定制款适配器--- 拆解(二)
  • 如何基于OpenCV和Sklearn库开展数据降维
  • 力扣11.盛最多水的容器
  • lxml 总结
  • CLion安装与配置教程
  • 从无人驾驶汽车到虚拟助手:人工智能如何改变我们的世界
  • 亿胜盈科 HT4182,HT4186,HT4188 电量均衡 同步升压型 双节理电池充电器
  • 机器人制作开源方案 | 自主型收集餐盘机器人
  • 请按长度为8拆分字符串
  • Qt之QGraphicsView —— 笔记1:绘制简单图元(附完整源码)
  • 美图发布自研视觉大模型4.0,主打AI设计与AI视频【无际Ai分享资讯】
  • 养生茶饮行业分析:2023年中国市场消费需求
  • JSON 语法详解:轻松掌握数据结构(上)
  • 还记得当初自己为什么选择计算机?
  • vue+jsonp编写可导出html的模版,可通过外部改json动态更新页面内容
  • Visual Studio 快捷键记录
  • 时间选择器
  • 9-tornado-Template优化方法、个人信息案例、tornado中ORM的使用(peewee的使用、peewee_async)、WTForms的使用