在并发多线程的情况下,为了保证数据安全性,一般我们会对数据进行加锁,通常使用Synchronized或者ReentrantLock同步锁。Synchronized是基于JVM实现,而ReentrantLock是基于Java代码层面实现的,底层是继承的AQS。
成都创新互联专注于章丘网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供章丘营销型网站建设,章丘网站制作、章丘网页设计、章丘网站官网定制、小程序设计服务,打造章丘网络公司原创品牌,更为您提供章丘网站排名全网营销落地服务。
AQS全称**AbstractQueuedSynchronizer**,即抽象队列同步器,是一种用来构建锁和同步器的框架。
我们常见的并发锁ReentrantLock、CountDownLatch、Semaphore、CyclicBarrier都是基于AQS实现的,所以说不懂AQS实现原理的,就不能说了解Java锁。
当我仔细研究AQS底层加锁原理,发现竟然跟Synchronized加锁原理有惊人的相似。让我突然想到一句名言,记不清怎么说了,意思是框架底层原理很相似,大家多学习底层原理。
Synchronized的加锁流程在前几篇文章已经详细讲过,没看过一块再温习一下。
我们先想一下Synchronized的加锁需求,如果让你设计Synchronized的对象锁存储结构,该怎么设计?
上面描述了Synchronized的加锁流程,Synchronized的对象锁存储结构是不是跟咱们想的一样?实际就是的。
下面是对象锁的存储数据结构(由C++实现):
ObjectMonitor() {
_header = NULL;
_count = 0;
_waiters = 0,
_recursions = 0;
_object = NULL;
_owner = NULL; // 持有锁的线程
_WaitSet = NULL; // 等待队列,存储处于wait状态的线程
_WaitSetLock = 0 ;
_Responsible = NULL ;
_succ = NULL ;
_cxq = NULL ;
FreeNext = NULL ;
_EntryList = NULL ; // 阻塞队列,存储处于等待锁block状态的线程
_SpinFreq = 0 ;
_SpinClock = 0 ;
OwnerIsThread = 0 ;
}
上图展示了对象锁的基本工作机制:
Synchronized对象锁存储结构和加锁流程,竟然跟咱们想的一样。
再看一下AQS的存储结构和加锁流程,有没有相似的地方。
先分析一下,我们使用AQS的加锁需求:
AQS的需求跟Synchronized一模一样。
我们再看一下AQS实际的加锁机制是怎么设计的?是不是跟Synchronized相似?
AQS的加锁流程并不复杂,只要理解了同步队列和条件队列,以及它们之间的数据流转,就算彻底理解了AQS。
可以看到AQS和Synchronized的加锁流程几乎是一模一样的,AQS中同步队列就是Synchronized中EntryList,AQS中条件队列就是Synchronized中的waitSet,两个队列之间的数据转移流程也是一样的。
AQS跟Synchronized的加锁流程是一样的,都是通过同步队列和条件队列实现的,阻塞状态的线程被放到同步队列中,等待状态的线程被放到条件队列中,从条件队列唤醒的线程又被转移到同步队列末尾,一块竞争锁。
看完AQS加锁流程,还没有人不懂AQS的?
下篇文章再讲一下AQS加锁具体的源码实现。里面有很多精巧的设计,值得我们学习。
比如:
为什么同步队列要设计成双向链表?而条件队列要设计成单链表?
为什么AQS加锁性能这么好(乐观锁CAS使用)?
同步队列和条件队列中节点怎么用一个对象实现?
释放锁后,怎么唤醒同步队列中线程?
当前名称:重大发现,AQS加锁机制竟然跟Synchronized有惊人的相似
标题路径:http://www.shufengxianlan.com/qtweb/news9/485109.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联