高并发编程的成神之路--3.AbstractQueuedSynchronized(AQS)源码底层分析

AbstractQueuedSynchronized(AQS)详解

在研究一个类的时候先读它的原代码这样能有一个整体的认识(下面只是截取了部分,需要看的自己把后面的看完)

 源码分析:

查看ReentrantLock类的lock()方法

可以看到它本身调用的是同步方法

由于存在公平锁和非公平锁 

 

 

 

在这个里面存在着一个可重入锁的概念。 

 

 非公平锁:

还是一个之前手写可重入锁的概念,获取当前线程,修改状态值c,然后设置独占线程

 在重入之后可以直接返回true继续执行,而不会锁死

如果拿到锁了,就不执行后面的,没拿到继续执行后面的语句

 这里面就相比来说比较复杂

Node.EXCLUSIVE独占 

 

 就是一个链表,将进入的新的结点添加进去

 

 enq()方法,当没有尾节点,那就将node作为尾节点存放

 

上面我们已经将所有等待的线程放入到等待双向链表中,但是并没有阻塞它

回到 acquireQueued()

 如果当前结点(等待双向链表的尾节点)的前面一个结点是头结点,那就将它踢出去,将自己设置为头结点

 如果当前双链表中存在三个及三个以上结点,执行下面的语句

如果为等待状态返回true 

 

取消状态

 

 移除掉取消状态的结点(判断的是node结点的前一个结点)

 如果是小于0的,就将结点设置为等待

ShouldParkAfterFailAcquire()方法只有当结点是singal(等待状态的时候)返回true。

继续执行后面的

 让当前线程真正处于等待状态

 现在的话基本上加锁流程就结束了。

现在看解锁:

 首先就是进行c的状态-1

 如果当前线程不是独占线程(之前没有进行lock)

 c其实就是一个计数器,记录当前线程拿了几个锁,拿一个锁(lock)+1,释放一个锁(unlock)-1

如果c为0说明就没有线程拿锁,就可以直接释放独占线程资源

 回到release方法

有独占线程tryRelease就返回false,没有独占线程就返回true

 头结点不为null,不等于0说明当前头结点为等待状态

 这行来说意义不大,不需要研究

node的下一个结点为空,那就将尾节点赋给它的下一个结点

 如果不为空,就叫醒当前结点上的线程去争夺CPU资源

总结:AQS主要是通过一条双向链表和一个状态值来维护的 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值