ReentrantLock 加锁浅析

本文主要介绍ReentrantLock的整体结构,它依靠内部Sync变量实现锁功能,Sync继承自AQS。核心逻辑在AQS,Sync子类重写获取和释放方法实现公平和非公平锁。还阐述了加锁过程,包括调用加锁方法、尝试获取锁,失败后入队及阻塞线程等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ReentrantLock 整体结构
在这里插入图片描述

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

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

在这里插入图片描述

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

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

在这里插入图片描述
第一步:调用子类实现的获取锁的方法 tryAcquire 成功则结束if
Reentrantlock中两个子类的尝试修改锁状态方法
非公平 不判断当前是否还有其他节点在队列中 hasQueuedPredecessors
-在这里插入图片描述-在这里插入图片描述

有head.next节点 且节点不是当前线程 (h != t &&((s = h.next) == null) 新节点入队的时候可能产生
在这里插入图片描述

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值