Java 并发编程:AQS 的原子性如何保证

Wesley13
• 阅读 655

当我们研究AQS框架时(对于AQS不太熟知可以先阅读《什么是JDK内置并发框架AQS》,会发现AbstractQueuedSynchronizer这个类很多地方都使用了CAS操作。在并发实现中CAS操作必须具备原子性,而且是硬件级别的原子性。我们知道Java被隔离在硬件之上,硬件级别的操作明显力不从心。这时为了能够执行操作系统层面的操作,就必须要通过用C++编写的native本地方法来扩展实现。一般可以通过JNI方式实现Java代码调用C++代码

Java 并发编程:AQS 的原子性如何保证

Unsafe调用

JDK提供了一个类来满足CAS的硬件级别原子性要求,即sun.misc.Unsafe类,从名字上大概知道它用于执行低级别、不安全的操作,AQS就是使用此类来完成硬件级别的原子操作。也就是说通过该类就能实现对处理器的原子操作,Unsafe通过JNI调用本地C++代码,C++代码调用了硬件指令集,这些硬件指令集都属于CPU。

Java 并发编程:AQS 的原子性如何保证

Unsafe的魔法

Unsafe是一个很强大的类,它可以分配内存、释放内存、可以定位对象某字段的位置、可以修改对象的字段值、可以使线程挂起、使线程恢复、可进行硬件级别原子的CAS操作等等。

Java 并发编程:AQS 的原子性如何保证

Unsafe的用途

因为存在安全性问题,所以如果我们要用Unsafe类则需要另辟蹊径。可行的方法就是通过反射来绕过上述的安全检查,我们可以通过以下的getUnsafeInstance方法来获取Unsafe实例。这段代码演示了如何获取Java对象的相对地址偏移量以及使用Unsafe来完成CAS操作,最终输出的是flag字段的内存偏移量及CAS操作后的值。最终的输出为“unsafeTest对象的flag字段的地址偏移量为:12”和“CAS操作后的flag值为:101”。另外如果使用开发工具如Eclipse,可能会编译通不过,只要把编译错误提示关掉即可。

Java 并发编程:AQS 的原子性如何保证

Unsafe实现CAS

因为存在安全性问题,所以如果我们要用Unsafe类则需要另辟蹊径。可行的方法就是通过反射来绕过上述的安全检查,我们可以通过以下的getUnsafeInstance方法来获取Unsafe实例。这段代码演示了如何获取Java对象的相对地址偏移量以及使用Unsafe来完成CAS操作,最终输出的是flag字段的内存偏移量及CAS操作后的值。最终的输出为“unsafeTest对象的flag字段的地址偏移量为:12”和“CAS操作后的flag值为:101”。另外如果使用开发工具如Eclipse,可能会编译通不过,只要把编译错误提示关掉即可。

Java 并发编程:AQS 的原子性如何保证

总结

这里主要讲解了Unsafe类如何让Java层能实现硬件级别的原子操作,同时也了解了Unsafe类拥有很多法魔技能。通常我们使用Java时不需要在内存中处理Java对象及内存地址位置,但有的时候我们被迫必须要操作Java对象相关的地址,于是我们只能使用Unsafe类。使用该类则意味着破坏了Java平台隔离的效果了,我们都知道一旦用了本地方法则可能会引来跨平台问题。

Java 并发编程

Java 并发编程:AQS 的原子性如何保证

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
Java并发编程:AQS对CLH锁的优化
自旋锁适用于锁占用时间短,即锁保护临界区很小的情景<AQS的自旋锁详解(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU3OTc1MDM1Mg%3D%3D%26mid%3D2247495307%26idx%3D1%26sn
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
Java 并发编程:AQS 的自旋锁
互斥锁在AQS的互斥锁与共享锁(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU3OTc1MDM1Mg%3D%3D%26mid%3D2247495259%26idx%3D1%26sn%3D56465c833f62a64b1
Wesley13 Wesley13
3年前
Java并发编程:AQS的自旋锁
互斥锁在AQS的互斥锁与共享锁(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU3OTc1MDM1Mg%3D%3D%26mid%3D2247495259%26idx%3D1%26sn%3D56465c833f62a64b1
Wesley13 Wesley13
3年前
Java 并发编程:如何防止在线程阻塞与唤醒时死锁
Java并发编程:多线程如何实现阻塞与唤醒(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU3OTc1MDM1Mg%3D%3D%26mid%3D2247494798%26idx%3D1%26sn%3D4b27253ee84
Wesley13 Wesley13
3年前
Java并发编程:AQS的原子性如何保证
当我们研究AQS框架时(对于AQS不太熟知可以先阅读《什么是JDK内置并发框架AQS(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU3OTc1MDM1Mg%3D%3D%26mid%3D2247495050%26idx%3
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这