JUC并发编程(7)——Unsafe

Unsafe

一、介绍

Unsafe类在sun.misc包下,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。但是正如它的名字,使用它会增加程序出错的概率,使程序变得不安全。

二、获取Unsafe实例

Unsafe类源码

Unsafe类被设计成单例,提供了一个静态方法getUnsafe获取Unsafe实例。但是调用该方法的类必须为引导类加载器所加载,否则抛出SecurityException异常。

public class Unsafe { 
    // 单例对象 
    private static final Unsafe theUnsafe; 
    private Unsafe() {
    }
	static {
        Reflection.registerMethodsToFilter(Unsafe.class, new String[]{"getUnsafe"});
        theUnsafe = new Unsafe();
    }
        
    @CallerSensitive 
    public static Unsafe getUnsafe() { 
        Class var0 = Reflection.getCallerClass(); 
        // 仅在引导类加载器`BootstrapClassLoader`加载时才合法 
        if(!VM.isSystemDomainLoader(var0.getClassLoader())) { 
            throw new SecurityException("Unsafe");
        } else { 
            return theUnsafe; 
        } 
    } 

通过反射获取单例对象

Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
unsafe = (Unsafe) theUnsafe.get(null);

三、功能介绍

Unsafe提供的Api大致可分为以下几部分:
请添加图片描述

3.1 CAS操作

主要包含三个CAS操作的api:

/**
	*  CAS
  * @param o         包含要修改field的对象
  * @param offset    对象中某field的偏移量
  * @param expected  期望值
  * @param update    更新值
  * @return          true | false
  */
public final native boolean compareAndSwapObject(Object o, long offset,  Object expected, Object update);

public final native boolean compareAndSwapInt(Object o, long offset, int expected,int update);
  
public final native boolean compareAndSwapLong(Object o, long offset, long expected, long update);

CAS操作包含三个操作数——内存位置,预期原值及新值。执行CAS操作的时候,将内存位置的值与预期原值比较,如果相匹配,那么处理器会自动将该位置值更新为新值,否则处理器不做任何操作。CAS是一条CPU的原子指令(cmpxchg),比较并替换。

3.2 内存操作

这部分主要包含堆外内存的分配、拷贝、释放、给定地址操作等方法。

//分配内存, 相当于C++的malloc函数
public native long allocateMemory(long bytes);
//扩充内存
public native long reallocateMemory(long address, long bytes);
//释放内存
public native void freeMemory(long address);
//在给定的内存块中设置值
public native void setMemory(Object o, long offset, long bytes, byte value);
//内存拷贝
public native void copyMemory(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);
//获取给定地址值,忽略修饰限定符的访问限制。与此类似操作还有: getInt,getDouble,getLong,getChar等
public native Object getObject(Object o, long offset);
//为给定地址设置值,忽略修饰限定符的访问限制,与此类似操作还有: putInt,putDouble,putLong,putChar等
public native void putObject(Object o, long offset, Object x);
//获取给定地址的byte类型的值(当且仅当该内存地址为allocateMemory分配时,此方法结果为确定的)
public native byte getByte(long address);
//为给定地址设置byte类型的值(当且仅当该内存地址为allocateMemory分配时,此方法结果才是确定的)
public native void putByte(long address, byte x);

参考文章:

  1. 美团技术文
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值