共计 1394 个字符,预计需要花费 4 分钟才能阅读完成。
当咱们钻研 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 并发编程:过程、线程、并行与并发