Unsafe的应用
要想把java并发包学好,并明白其底层的设计原理,Unsafe类你不能不去研究一下。下面介绍一下Unsafe类的功能以及它在JDK中的应用。
一、分配内存和释放内存
功能:类中提供的3个本地方法allocateMemory、reallocateMemory、freeMemory分别用于分配内存,扩充内存和释放内存。
应用:在java nio包里有一个DirectByteBuffer,其对象所引用的空间是JVM堆以外的内存,又称直接内存,此内存的分配就是调用unsafe对象的allocateMemory实现。
二、定义对象某字段的偏移地址,并通过偏移地址修改或获得某对象的字段
功能:通过调用Unsafe对象的objectFieldOffset,传入一个Field参数,可以获取到此Feild参数所在对象的偏移地址(一个long型的整数)。然后调用putXXX方法修改某个对象的此feild的值
应用:LockSupport类的park(Object blocker)方法,当调用此方法时,此方法会调用unsafe的putObject方法,将blocker对象设置到当前线程的parkBlocker字段上
三、挂起和恢复线程
功能:调用Unsafe的park方法可以挂起一个线程,调用unpark可以恢复一个线程
应用:LockSupport类的park方法和unpark方法都是调用的unsafe的对应方法。详情可以阅读源码
四、CAS
功能:CAS 就是比较和设置的缩写。这是原子性线程安全操作的重要思想,类似于hibernate的乐观锁。其原理是:CAS操作有3个操作数,内存值M,预期值E,新值U,如果M==E,则将内存值修改为U,否则啥都不做。。代码形式如下:
while(true){
int a = get();
int newVal = a+1;
if(unsafe.compareAndSwapInt(a,newVal)){//如果设置成功则跳出死循环,否则一直循环下去,直到设置新值成功。
break;
}
}
CAS功能的实现就是通过调用Unsafe对象的compareAndSwapXXX()方法,此方法时本地实现,与系统底层密切相关,CAS是一个cpu指令,所以它具有原子性,也就是说,Unsafe的compareAndSwap方法从内存里取值,然后比较,在通过比较结果进行设置新值的操作都是原子性不可分割的。
应用:unsafe的此功能在java并发包用的是相当的多。比如并发包的锁机制,非阻塞的队列,还有atomicXXX这些原子类也都使用了Unsafe的这个功能。详情可以看源码。
这是获取Unsafe对象的方法:
public static Unsafe getUnsafe() throws Exception{
Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeInstance.setAccessible(true);
return (Unsafe) theUnsafeInstance.get(Unsafe.class);
}
总结:个人觉着学习并发包,不应该照着API文档去读每个类每个方法的用法,而是找一下案例看一下大概是如何使用,这样你可以很快速的会使用这些类,如果还有什么疑惑,或者想明白其中原理,可以直接查看源代码,当然你可以大体看一下了解一下原理,没必要死扣非得要完全搞明白。会用用好就挺好的。嘿嘿,不早了,先写到这吧。希望大家给我指出宝贵的意见
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?