当咱们钻研AQS框架时(对于AQS不太熟知能够先浏览《什么是JDK内置并发框架AQS》,会发现AbstractQueuedSynchronizer这个类很多中央都应用了CAS操作。在并发实现中CAS操作必须具备原子性,而且是硬件级别的原子性。咱们晓得Java被隔离在硬件之上,硬件级别的操作显著力不从心。这时为了可能执行操作系统层面的操作,就必须要通过用C++编写的native本地办法来扩大实现。个别能够通过JNI形式实现Java代码调用C++代码
Unsafe调用
JDK提供了一个类来满足CAS的硬件级别原子性要求,即sun.misc.Unsafe类,从名字上大略晓得它用于执行低级别、不平安的操作,AQS就是应用此类来实现硬件级别的原子操作。也就是说通过该类就能实现对处理器的原子操作,Unsafe通过JNI调用本地C++代码,C++代码调用了硬件指令集,这些硬件指令集都属于CPU。
Unsafe的魔法
Unsafe是一个很弱小的类,它能够分配内存、开释内存、能够定位对象某字段的地位、能够批改对象的字段值、能够使线程挂起、使线程复原、可进行硬件级别原子的CAS操作等等。
image.png
Unsafe的用处
因为存在安全性问题,所以如果咱们要用Unsafe类则须要另辟蹊径。可行的办法就是通过反射来绕过上述的安全检查,咱们能够通过以下的getUnsafeInstance办法来获取Unsafe实例。这段代码演示了如何获取Java对象的绝对地址偏移量以及应用Unsafe来实现CAS操作,最终输入的是flag字段的内存偏移量及CAS操作后的值。最终的输入为“unsafeTest对象的flag字段的地址偏移量为:12”和“CAS操作后的flag值为:101”。另外如果应用开发工具如Eclipse,可能会编译通不过,只有把编译谬误提醒关掉即可。
Unsafe实现CAS
因为存在安全性问题,所以如果咱们要用Unsafe类则须要另辟蹊径。可行的办法就是通过反射来绕过上述的安全检查,咱们能够通过以下的getUnsafeInstance办法来获取Unsafe实例。这段代码演示了如何获取Java对象的绝对地址偏移量以及应用Unsafe来实现CAS操作,最终输入的是flag字段的内存偏移量及CAS操作后的值。最终的输入为“unsafeTest对象的flag字段的地址偏移量为:12”和“CAS操作后的flag值为:101”。另外如果应用开发工具如Eclipse,可能会编译通不过,只有把编译谬误提醒关掉即可。
总结
这里次要解说了Unsafe类如何让Java层能实现硬件级别的原子操作,同时也理解了Unsafe类领有很多法魔技能。通常咱们应用Java时不须要在内存中解决Java对象及内存地址地位,但有的时候咱们被迫必须要操作Java对象相干的地址,于是咱们只能应用Unsafe类。应用该类则意味着毁坏了Java平台隔离的成果了,咱们都晓得一旦用了本中央法令可能会引来跨平台问题。
Java 并发编程
- Java并发编程:AQS的原子性如何保障
- Java并发编程:如何避免在线程阻塞与唤醒时死锁
- Java并发编程:多线程如何实现阻塞与唤醒
- Java并发编程:工作执行器Executor接口
- Java并发编程:并发中死锁的造成条件及解决
- Java并发编程:Java 序列化的工作机制
- Java并发编程:过程、线程、并行与并发