ReentrantLock 加锁浅析

ReentrantLock 整体结构
ReentrantLock 加锁浅析_第1张图片

ReentrantLock 依靠内部的Sync变量 实现锁的功能

Sync抽象类继承自AQS
1:AQS实现同步框架(构建同步队列,控制同步状态) 预留出了获取和释放共享资源的方法供子类实现
2:也就是说Sync 及它的实现类只是重写了获取和释放的方法 核心逻辑在AQS中
3:加Sync抽象类为了让子类重写lock 和tryacquire 实现公平和非公平锁
4:公平和非公平优缺点 线程是否有机会被饿死 及 线程切换量进而影响的程序吞吐量
5:为什么nonfairTryAcquire不在子类实现 而在抽象类中 为公平锁也提供非公平锁的获取方法

ReentrantLock 加锁浅析_第2张图片

三:加锁
1:调用sync的加锁方法
Reentrantlock加锁
在这里插入图片描述
FairSync加锁
NonfairSync加锁
:非公平锁多了一个 cas操作 提前抢占锁
在这里插入图片描述ReentrantLock 加锁浅析_第3张图片

2 尝试获取锁 AQS实现的方法

ReentrantLock 加锁浅析_第4张图片
第一步:调用子类实现的获取锁的方法 tryAcquire 成功则结束if
Reentrantlock中两个子类的尝试修改锁状态方法
非公平 不判断当前是否还有其他节点在队列中 hasQueuedPredecessors
-ReentrantLock 加锁浅析_第5张图片-ReentrantLock 加锁浅析_第6张图片

有head.next节点 且节点不是当前线程 (h != t &&((s = h.next) == null) 新节点入队的时候可能产生
ReentrantLock 加锁浅析_第7张图片

第二步:失败 进去 acquireQueued(addWaiter(Node.EXCLUSIVE), arg)
addWaiter 将当前线程节点入队 先cas快速入队 失败进入循环cas入队
ReentrantLock 加锁浅析_第8张图片ReentrantLock 加锁浅析_第9张图片
第三步 acquireQueued 尝试将线程阻塞 需要循环向前查找非取消的节点 然后才能进行阻塞 即 前一个节点非cancel 然后设置成SIGNAL 状态 这样前节点的线程如果释放了同步状态或者被取消时候会通知本线程
ReentrantLock 加锁浅析_第10张图片

你可能感兴趣的:(笔记)