unsafe操作java对象_Unsafe - java堆对象的常用操作解析

java不能直接访问操作系统底层,而是通过本地方法来访问。Unsafe类提供了硬件级别的原子操作,以及堪比C语言的操作内存的方便性。但是在生产环境下不建议使用,本文主要是通过Unsafe工具来更深刻的理解Java源码的实现原理。

这篇博文主要讲通过双寄存器模式操作java堆对象上变量域的方法

getUnsafe()单例模式获取Unsafe对象

用户代码调用此方法将抛出安全异常,但是可以通过反射获取

5daccd15a71a?from=groupmessage

CAS操作系列

CAS操作提供了硬件级别操作内存读写和锁的语义,在多处理器系统中,通过硬件指令组合:Lock + cmpxchg 来实现对一组先读后写的内存操作的原子性(不被其他线程中断),同时具有volatile变量读写的内存语义。lock指令用来刷新主内存,cmpxchg 指令进行接下来的读写,这两条指令保证了CAS操作的原子性和值更新的可见性,但是不保证接下来的对普通变量的访问能读到最新的值,所以一般CAS搭配volatile变量一起使用,从而始终都能保证读到最新的值,而不是仅仅CAS更新的时候。

所以通常情况下 CAS + volatile 搭配使用

5daccd15a71a?from=groupmessage

volatile变量读写语义的操作系列

对对象的普通域进行具有volatile读/写的语义的操作

5daccd15a71a?from=groupmessage

5daccd15a71a?from=groupmessage

5daccd15a71a?from=groupmessage

volatile写语义的延迟操作系列

5daccd15a71a?from=groupmessage

需要注意的是:此方法组的含义使用来操作volatile变量域,实现了延迟操作的功能呢,即方法操作的变量域只有下次被以volatile读写的形式被访问之前,putOrderedxxx方法系列才会刷新缓存,这将使得volatile变量快速的写操作被允许,将volatile写性能消耗延迟到下一次volatile变量的读/写前发生。在下一次volatile读写前,当前操作的结果不保证线程间可见性。(描述错误,应该能保证可见性,见上面分析)

普通变量域的读写语义操作

5daccd15a71a?from=groupmessage

此方法组不具备volatile读写的内存语义,也不具备volatile延迟写的内存语义。即使操作的域变量被volatile修饰,也不会立即刷新到主内存,更不会延迟刷新。不保证内存的可见性。

需要注意:volatile变量域与Unsafe的对象域读写之间的关系

不管变量域是否被volatile修饰,在内存中存储对象时都是不知道的,而Unsafe工具是在运行时操作内存对象的,所以要通过需要的内存语义来选择Unsafe工具方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值