获取独占式锁
2021-07-15 16:44:36 1 举报
独占式同步状态获取流程,也就是AQS中acquire(int arg)方法调用流程
作者其他创作
大纲/内容
否
只有当前驱节点为头节点时才可以尝试获取同步状态,原因有二:第一:头节点是成功获取到同步状态的节点,而头节点释放了同步状态之后,将会唤醒其后继节点,后继节点的线程被唤醒后需要检查自己的前驱节点是否是头节点;第二:维护同步队列的FIFO原则
当前节点的前驱节点是否为头节点
ddWaiter(Node mode)方法将线程包装成节点并进行入队
CAS新建头节点,头指针、尾指针都指向该节点
成功
将当前线程包装成Node节点
失败
直接将当前节点CAS尾插入到同步队列中
获取同步状态
已初始化
将当前节点设置为头节点,并且将之前的头节点与队列断开,方便GC回收
将当前节点CAS尾插入到同步队列中
acquire(int arg)方法开始
失败自旋
1,将当前节点的前驱节点的状态设置成SIGNAL2.park方法阻塞当前线程
在获取同步状态时,同步器维护一个同步队列。 线程获取同步状态(同步锁)失败,被封装成Node进行入队操作,核心方法在于addWaiter()和enq(),enq()完成对同步队列头节点的初始化工作以及利用CAS完成对入队操作失败的重试 线程获取锁是一个自旋的过程,当且仅当当前节点的前驱节点是头节点并且线程获取到同步状态时,节点出队(停止自旋)即节点引用的线程获取到锁。否则,当不满足条件时就会引用LockSupport.park()方法使得线程阻塞。 在释放同步状态(同步锁)时,同步器调用tryRelease(int arg)方法释放同步状态,然后通过LockSupport.unpark()方法唤醒头节点的后继节点
enq方法
同步队列是否已经初始化(判断尾节点是否为null)
获取同步状态(独占式锁)是否成功
是
退出返回
tryAcquire(arg)
线程被中断或前驱节点被释放
同步队列尾节点(tail)是否为null
首次入队失败,调用enq()方法再次入队
未初始化
自旋
0 条评论
回复 删除
下一页