AbstractQueuedSynchronizer(AQS)锁的时序图
2020-05-13 14:57:24 0 举报
AbstractQueuedSynchronizer(AQS)锁的时序图
作者其他创作
大纲/内容
清除Node.CANCELLED状态的节点
失败
将当前节点设置为Node.SIGNAL
lock.lock()
sync.lock
添加当前节点入队到队尾
ws 0
判断tail是否为空
ReentrantLock
调用tryAcquire尝试再次获取锁
是
获取成功
为空
调用子类内部类Sync.lock()
获取失败
抢占成功,设置当前线程setExclusiveOwnerThread(Thread.currentThread())
成功
子类具体实现如何获取锁tryAcquire(1)
子类继承父类acquire()方法
调用tryAcquire尝试获取锁
设置当前节点为头节点head
AbstractOwnableSynchronizer
生成阻塞对列节点addWaiter(Node.EXCLUSIVE)
抢占失败acquire(1)
将当成线程包装成一个Node节点
AbstractQueuedSynchronizer(AQS)锁的时序图
true - 抢占锁成功,设置当前线程为抢占线程false - 抢占失败,调用 acquire(1)
Opt[抢占锁]
将当前节点设置为新的尾节点tail
public class Main { static final Lock lock = new ReentrantLock(); public static void main(String[] args) { lock.lock(); try { TimeUnit.SECONDS.sleep(1); // 具体业务代码 } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock(); } }}
返回最新添加的尾节点执行acquireQueued
添加失败
当前节点的前节点是head时,抢占锁:成功,执行线程,设置头节点。失败,则需将线程挂起
Opt[入队列,执行或阻塞]
更改state状态退出
获取锁
selfInterrupt()
抢锁失败,生成Node,入等待队列
Alt[再抢锁,失败入队]
ReentrantLock.NonfairSync
ReentrantLock.Sync
nonfairTryAcquire(acquires)
不为空
将当前线程阻塞,执行顾挂起操作
判断当前节点的前节点是否是head节点
否
!tryAcquire(arg)
调用子类内部类具体实现锁的lock()
addWaiter
调用LockSupport.pack(this)阻塞parkAndCheckInterrupt()
判断前置节点的状态
Lock
执行enq方法,自旋添加节点
结束
ws = Node.SIGNAL
node - 入队后的尾节点
acquireQueue
子类实现lock方法
开始
等待队列尾节点不为空,当前节点替换尾节点,入队;调用enq(node): 自旋,替换尾节点
Opt[pred=tail != null]
抢占锁结果true|false
设置state的值
自旋,替换尾节点enq(node)
自旋操作
0 条评论
下一页