JAVA之Unsafe学习笔记

本文详细介绍了JAVA中的sun.misc.Unsafe,包括其作用、获取实例的方式、重点API及其使用场景。Unsafe提供了底层内存操作,如CAS原子操作,可用于高性能并发和内存管理,但使用需谨慎,避免引发内存崩溃和安全问题。
摘要由CSDN通过智能技术生成

sun.misc.Unsafe

作用:可以用来在任意内存地址位置处读写数据,支持一些CAS原子操作
Java最初被设计为一种安全的受控环境。尽管如此,HotSpot还是包含了一个后门sun.misc.Unsafe,提供了一些可以直接操控内存和线程的底层操作。Unsafe被JDK广泛应用于java.nio和并发包等实现中,这个不安全的类提供了一个观察HotSpot JVM内部结构并且可以对其进行修改,但是不建议在生产环境中使用

获取Unsafe实例

Unsafe对象不能直接通过new Unsafe()或调用Unsafe.getUnsafe()获取,原因如下:

  • 不能直接new Unsafe(),原因是Unsafe被设计成单例模式,构造方法是私有的;
  • 不能通过调用Unsafe.getUnsafe()获取,因为getUnsafe被设计成只能从引导类加载器(bootstrap class loader)加载
@CallerSensitive
public static Unsafe getUnsafe() {
    Class var0 = Reflection.getCallerClass();
    if (!VM.isSystemDomainLoader(var0.getClassLoader())) {
        throw new SecurityException("Unsafe");
    } else {
        return theUnsafe;
    }
}

获取实例

//方法一:我们可以令我们的代码“受信任”。运行程序时,使用bootclasspath选项,指定系统类路径加上你使用的一个Unsafe路径
java -Xbootclasspath:/usr/jdk1.7.0/jre/lib/rt.jar:. com.mishadoff.magic.UnsafeClient

// 方法二
static {
    try {
        Field field = Unsafe.class.getDeclaredField("theUnsafe");
        field.setAccessible(true);
        UNSAFE = (Unsafe) field.get(null);
    } catch (Exception e) {
    }
}

注意:忽略你的IDE。比如:eclipse显示”Access restriction…”错误,但如果你运行代码,它将正常运行。如果这个错误提示令人烦恼,可以通过以下设置来避免:
Preferences -> Java -> Compiler -> Errors/Warnings -> Deprecated and restricted API -> Forbidden reference -> Warning

重点API

  • allocateInstance(Class<?> var1)不调用构造方法生成对象
User instance = (User) UNSAFE.allocateInstance(User.class);
  • objectFieldOffset(Field var1)返回成员属性在内存中的地址相对于对象内存地址的偏移量
  • putLong,putInt,putDouble,putChar,putObject等方法,直接修改内存数据(可以越过访问权限)
package com.quancheng;

import sun.misc.Unsafe;

import java.lang.reflect.Field;

public class CollectionApp {
   
    private static sun.misc.Unsafe UNSAFE;

    public static void main(String[] args) {
        try {
            User instance = (User) UNSAFE.allocateInstance(User.class);

            instance.setName("luoyoub");
            System.err.println("instance:" + instance);
            instance.test();

            Field name = instance.getClass().getDeclaredField("name");
            UNSAFE.putObject(instance, UNSAFE.objectFieldOffset(name), "huanghui");
            instance.test();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static {
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            UNSAFE = (Unsafe) field.get(null);
        } catch (Exception e) {
        }
    }
}

class User {
    private String name;

    public void setName(String name) {
        thi
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值