ReentrantLock流程逻辑图
2022-05-17 16:32:57 0 举报
ReentrantLock流程逻辑图
作者其他创作
大纲/内容
修改state值是否成功
parkAndCheckInterrupt方法将调用LockSupport.park(this)将线程挂起,下次被唤醒时进入下次循环
是
否
返回false
false
默认使用非公平锁
true
将exclusiveOwnerThread设置为null设置free为true
构建一个新的node节点,将当前线程封装到构建的node节点里获取当前队列的尾部节点pred=tail
调用tryAcquire(1)
p是否是head节点且tryAcquire方法返回true
说明前节点已经取消了自己,要移除这些ws大于0的节点
!hasQueuedPredecessors判断是否存在队列
判断c是否等于0
tryAcquire返回false
返回true
判断pred!=null
调用release(1)
将node节点前节指向pred
设置前节点的ws为SIGNAL
非公平锁的tryAcquire方法市实际调用的是nonfairTryAcquire方法
addWaiter(Node.EXCLUSIVE)
tryRelease(1)
调用acquire(1)方法
tryAcquire方法主要逻辑有2个1、如果state等于0,则通过cas操作修改seate值,同时将获取到锁的线程指向当前线程并返回true;2、如果state值不等于0,则判断当前获得锁的线程是否是当前线程,是则state加1并返回true;3、如果以上都不是,则直接返回false注意公平锁和非公平锁这里的差别在于非公平锁不判断阻塞队列是否存在直接尝试抢占锁
判断线程current是否等于exclusiveOwnerThread
pred的下一个节点指向node
parkAndCheckInterrupt
判断参数fair
抛出异常
acquireQueued
enq(node)方法
设置获取锁线程为当前线程
compareAndSetHead设置头节点head是否成功
拿到队列尾结点Node t=tail
使用公平锁FairSync
interrupted设置为true
进入下次循环
将state加1并更新state的值
判断t尾结点是否为null
将tail指向head
for (;;) 自旋
compareAndSetTail将node节点替换tail节点是否成功
enq方法逻辑
tryAcquire方法逻辑流程
将t的下一个节点指向node
Node h=head
判断当前线程是否与exclusiveOwnerThread相等
将node的前节点指向t
执行cancelAcquire
判断failed
addWaiter方法处理逻辑
tryRelease方法逻辑
设置头节点为node,将node节点的前一个节点的next指向null;设置failed为false
判断ws是否大于0
addWaiter方法主要做3件事:1、将当前线程封装成一个node节点;2、判断阻塞队列是否,如果存在则将上面封装的node节点尝试添加到队列尾部,添加失败则调用enq()方法通过自旋将node节点添加队尾;如果不存在贼调用enq()方法通过自旋初始化队列并将将node节点添加队尾3、返回封装的node节点
unlock方法逻辑
设置state值为c
setExclusiveOwnerThread方法设置为当前线程
new ReentrantLock(fair)
调用selfInterrupt方法响应线程中断请求
addWaiter返回node节点
返回free
调用lock()方法
h!=null且h.waitStatus!=0
tryAcquire返回true
获取锁成功
compareAndSetState方法修改state值是否成功
获取当前线程current获取当前state值
int ws=pred.waitStatus拿到pred节点的状态,这里的pred是node节点的前节点
使用非公平锁NonfairSync
hasQueuedPredecessors方法逻辑只有公平锁再会有,非公平锁没有这个逻辑
Node p=node.predecessor()拿到node节点的前一个节点
设置free为false
shouldParkAfterFailedAcquire方法处理逻辑
获取当前状态state减去releases的值c
lock.unlock()
判断ws是否等于Node.SIGNAL
acquireQueued流程逻辑 for (;;)
唤醒h节点对应的线程
判断state是否等0
收藏
0 条评论
下一页