资讯专栏INFORMATION COLUMN

5分钟 入门AQS

darcrand / 1859人阅读

摘要:同样的线程,线程,线程也阻塞挂起加入队列中。至此在时刻的队列如图时刻线程执行完毕,调用方法释放锁并从队列中取出哨兵节点的下一节点,也就是此刻的线程,并唤醒该线程。线程再次尝试获取锁,如果锁获取成功将继续执行线程代码。

AQS 全称:AbstractQueuedSynchronizer,它是JUC并发工具包中 ReentrantLock 、CountDownLatch、CyclicBarrier等这些类的底层实现。此篇我们主要通过ReentrantLock的使用来大体了解AQS底层代码设计原理,不对源码详细赘述。只要对整体的设计方向有清晰了解,再去追踪源码便不是什么难事。阅读本篇之前,需要大家对ReentrantLock 的API有一定了解。

ReentrantLock的lock、await方法底层逻辑

在使用ReentrantLock进行代码块同步,一般都会有如下写法:

ReentrantLock lock = new ReentrantLock(true);
Condition condition = lock.newCondition();

try{
    lock.lock();
    //.....
    condition.await();
    
 }finally{
    lock.unlock();
 }

假设 T1 时刻有10个线程调用同一个ReentrantLock实例的lock()方法, 线程1 先获取锁成功,紧接着线程2 调用lock()方法,发现获取锁失败(通过CAS操作对状态位进行标记),则线程2被封装成Node节点放入AQS双向队列中,并调用LockSupport.park()阻塞挂起。同样的线程3,线程4,...线程10 也阻塞挂起加入队列中。至此在t1时刻 AQS的队列如图1-1

T4 时刻线程1执行完毕,调用unlock()方法释放锁并从AQS队列中取出哨兵节点的下一节点,也就是此刻的线程2,并唤醒该线程。线程2再次尝试获取锁,如果锁获取成功将继续执行线程2代码。如果失败会被再次封装成Node节点放入AQS队列中去。看到这里大家可能会有疑问:为什么线程1的锁释放完后唤醒的是线程2,而不是线程3 或者线程 4 呢?这里是因为公平锁与非公平锁的原因,如果采用了公平锁那么将按照先进先出的原则让线程去抢占锁,而非公平锁没有先后顺序的限制。对于ReentrantLock可以通过构造函数的参数进行指定,默认它采用的是非公平锁。

Lock 与 Condition结合使用又是什么样的原理呢?

我们紧接着上面的分析,线程T1时刻获取锁成功后,在T2时刻调用了condition.await()方法时会发生以下4件事情:

释放锁(通过CAS操作对状态为进行标记)

阻塞挂起线程1

线程1封装成Node节点放入条件队列中(注意:此处条件队列和AQS队列不是一回事)

唤醒AQS队列中阻塞挂起的线程

当其他线程调用condition.signal() 或者 condition.sigalAll() 方法时,会将条件队列的一个或者全部Node节点移到AQS队列中。
一个锁对应一个AQS队列、多个condition、多个条件队列,条件队列的个数是跟随Condition走的。我们通过1-2图来更直观认识 Lock、Condition、AQS队列、条件队列之间的关系。

至此ReentrantLock底层使用AQS来实现线程同步的设计已讲解完毕,赶紧撸源码去吧!!!

清山绿水始于尘,博学多识贵于勤。
我有酒,你有故事吗?
公众号:「Java锦囊」。
欢迎一起谈天说地,聊Java。
书写技术文章是一个循序渐进的过程,所以我不能保证每句话、每行代码都是对的,但至少能保证不复制、不粘贴,每篇文章都是自己对技术的认识、细心斟酌总结出来的。乔布斯说:我们在这个星球上的时间都很短,很少有机会去做几件真正伟大的事情,同时要做得好,我必须要趁我还年轻的时候完成这些事。
其实我想说的是,我是一枚程序员,我只想在有限的时间内尽可能去沉淀我这一生中所能沉淀下来的东西。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/74439.html

相关文章

  • 高并发

    摘要:表示的是两个,当其中任意一个计算完并发编程之是线程安全并且高效的,在并发编程中经常可见它的使用,在开始分析它的高并发实现机制前,先讲讲废话,看看它是如何被引入的。电商秒杀和抢购,是两个比较典型的互联网高并发场景。 干货:深度剖析分布式搜索引擎设计 分布式,高可用,和机器学习一样,最近几年被提及得最多的名词,听名字多牛逼,来,我们一步一步来击破前两个名词,今天我们首先来说说分布式。 探究...

    supernavy 评论0 收藏0
  • 高并发

    摘要:表示的是两个,当其中任意一个计算完并发编程之是线程安全并且高效的,在并发编程中经常可见它的使用,在开始分析它的高并发实现机制前,先讲讲废话,看看它是如何被引入的。电商秒杀和抢购,是两个比较典型的互联网高并发场景。 干货:深度剖析分布式搜索引擎设计 分布式,高可用,和机器学习一样,最近几年被提及得最多的名词,听名字多牛逼,来,我们一步一步来击破前两个名词,今天我们首先来说说分布式。 探究...

    ddongjian0000 评论0 收藏0
  • 高并发

    摘要:表示的是两个,当其中任意一个计算完并发编程之是线程安全并且高效的,在并发编程中经常可见它的使用,在开始分析它的高并发实现机制前,先讲讲废话,看看它是如何被引入的。电商秒杀和抢购,是两个比较典型的互联网高并发场景。 干货:深度剖析分布式搜索引擎设计 分布式,高可用,和机器学习一样,最近几年被提及得最多的名词,听名字多牛逼,来,我们一步一步来击破前两个名词,今天我们首先来说说分布式。 探究...

    wangdai 评论0 收藏0
  • AQS简简单单过一遍

    摘要:我在面试题中也见过他的身影,但一直不知道是什么东西。直到当前线程被或者获取到资源,结束。简简单单把过一遍明天就看显式锁实现咯参考资料如果文章有错的地方欢迎指正,大家互相交流。为了大家方便,刚新建了一下群,大家也可以去交流交流。 前言 回顾前面: 多线程三分钟就可以入个门了! Thread源码剖析 多线程基础必要知识点!看了学习多线程事半功倍 Java锁机制了解一下 只有光头才能变强...

    EasonTyler 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<