Java魔法类Unsafe详解

本文详述了Java中的sun.misc.Unsafe类,它是一个用于底层操作的强大工具,包括获取实例的方式、提供的功能,如堆外内存管理、系统信息获取、对象字段操作、CAS原子操作等,并探讨了其源码中的native方法实现,尤其是以CAS指令为例,揭示了其在不同操作系统和CPU上的底层实现原理。
摘要由CSDN通过智能技术生成

前言

Unsafe是jdk提供操作的增强执行低级别代码和操作底层资源的工具类。jdk1.8及以下的版本在sun.misc包下,jdk11移到jdk.internal.misc包下。sum.misc继续保留,只是实现修改为代理jdk.internal.misc包的实例。下面我们来详细分解以下Unsafe的功能和实现。

使用方法

看Unsafe的源码,我们发现Unsafe类是单例实现的,提供静态方法获取Unsafe实例。

public final class Unsafe {
   
    private static final Unsafe theUnsafe;
    private Unsafe() {
   
    }

    @CallerSensitive
    public static Unsafe getUnsafe() {
   
        Class var0 = Reflection.getCallerClass();
        if (!VM.isSystemDomainLoader(var0.getClassLoader())) {
   
            throw new SecurityException("Unsafe");
        } else {
   
            return theUnsafe;
        }
    }
}

我们在此处看到调用类必须是引导类加载器所加载的类才能调用。否则会抛出SecurityException异常。
即,如果我们的类是引导类加载器所加载的类那么我们就可以直接调用Unsafe的getUnsafe()获取Unsafe的实例。像jdk中java.util.concurrent包的很多并发、原子类一样直接使用:

private static final Unsafe unsafe = Unsafe.getUnsafe();

当时在我们实际开发中我们类,一般不是被引导类加载的,那么这时我们改如何使用呢?

  1. 第一种:通过-Xbootclasspath、-Xbootclasspath/a 、-Xbootclasspath/p把调用Unsafe的类所在的jar被引导类加载器加载,从而可以直接获得unsafe实例。
  2. 第二种:通过反射获取单例对象theUnsafe
	Field field = Unsafe.class.getDeclaredField("theUnsafe");
	field.setAccessible(true);
	return (Unsafe) field.get(null);

推荐私用第二种方式。也是普遍的用户,如果还有其他方法,欢迎在文章后面留言探讨。

功能介绍

我们先来看一下Unsafe的代码,去除一些功能相似的代码,使用XXX代表不同的类型,简化阅读代码的难度。去除Deprecated标记的过期方法。本代码摘录自openjdk8u分支的jdk/src/share/classes/sun/misc/Unsafe.java。
通过整理分类,我们看到Unsafe主要提供了如下方法给我们使用:管理堆外内存、获取系统相关信息、(类、对象、字段、数组)的相关操作、CAS原子操作、线程相关操作、内存屏障。具体分类的详细方法在下面的源码整理中。

public final class Unsafe {
   

    private static native void registerNatives();
    static {
   
        registerNatives(
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值