🥂(❁´◡`❁)您的点赞👍➕评论📝➕收藏⭐➕关注👀是作者创作的最大动力🤞
💖📕🎉🔥 支持我:点赞👍+收藏⭐️+留言📝+关注👀欢迎留言讨论
🔥🔥🔥(源码获取 + 调试运行 + 问题答疑)🔥🔥🔥 有兴趣可以联系我
🔥🔥🔥 文末有往期免费源码,直接领取获取(无删减,无套路)
我们常常在当下感到时间慢,觉得未来遥远,但一旦回头看,时间已经悄然流逝。对于未来,尽管如此,也应该保持一种从容的态度,相信未来仍有许多可能性等待着我们。
🔥🔥🔥(免费,无删减,无套路):java swing管理系统源码 程序 代码 图形界面(11套)」
链接:https://pan.quark.cn/s/784a0d377810
提取码:见文章末尾
🔥🔥🔥(免费,无删减,无套路): Python源代码+开发文档说明(23套)」
链接:https://pan.quark.cn/s/1d351abbd11c
提取码:见文章末尾
🔥🔥🔥(免费,无删减,无套路):计算机专业精选源码+论文(26套)」
链接:https://pan.quark.cn/s/8682a41d0097
提取码:见文章末尾
🔥🔥🔥(免费,无删减,无套路):Java web项目源码整合开发ssm(30套)
链接:https://pan.quark.cn/s/1c6e0826cbfd
提取码:见文章末尾
🔥🔥🔥(免费,无删减,无套路):「在线考试系统源码(含搭建教程)」
链接:https://pan.quark.cn/s/96c4f00fdb43
提取码:见文章末尾
前言
在多线程编程中,锁是保证线程安全的重要工具。Java提供了丰富的锁机制,其中AbstractQueuedSynchronizer(AQS)作为并发包的核心基础框架,支撑了ReentrantLock、CountDownLatch等众多同步器的实现。今天,我将带领大家深入AQS内部,从零开始实现一个简单的互斥锁,通过实战来理解AQS的工作原理。
AQS核心原理回顾
在开始编码之前,我们先简要回顾AQS的核心机制。AQS通过一个FIFO队列来管理获取锁失败的线程,并通过一个volatile的state变量来表示同步状态。其核心思想是:
-
当线程尝试获取锁时,如果state表示锁可用,则获取成功
-
如果锁已被占用,则将当前线程封装为Node节点加入队列等待
-
当前驱节点释放锁时,会唤醒后继节点重新尝试获取
简单互斥锁的实现
下面我们基于AQS实现一个最简单的不可重入互斥锁Mutex:
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Lock;
public class Mutex implements Lock {
// 内部同步器,继承AQS
private static class Sync extends AbstractQueuedSynchronizer {
// 尝试获取锁:state为0表示未锁定,1表示已锁定
@Override
protected boolean tryAcquire(int acquires) {
// 使用CAS操作尝试将state从0改为1
if (compareAndSetState(0, 1)) {
// 成功设置state为1,表示获取锁成功
// 设置当前线程为独占所有者
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
// 尝试释放锁
@Override
protected boolean tryRelease(int releases) {
// 检查当前线程是否持有锁
if (getState() == 0 || !isHeldExclusively()) {
throw new IllegalMonitorStateException();
}
// 清除独占所有者
setExclusiveOwnerThread(null);
// 将state设置为0,不需要CAS因为只有持有者能释放
setState(0);
return true;
}
// 判断当前线程是否独占资源
@Override
protected boolean isHeldExclusively() {
return getExclusiveOwnerThread() == Thread.currentThread();
}
}
private final Sync sync = new Sync();
@Override
public void lock() {
sync.acquire(1);
}
@Override
public void unlock() {
sync.release(1);
}
// 其他Lock接口方法的简单实现...
@Override
public boolean tryLock() {
return sync.tryAcquire(1);
}
@Override
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
@Override
public boolean tryLock(long timeout, java.util.concurrent.TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
}
核心方法深度解析
tryAcquire方法
tryAcquire是获取锁的核心方法,其实现体现了AQS的精妙之处:
protected boolean tryAcquire(int acquires) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
这里使用了CAS(Compare-And-Swap)操作,这是一个原子操作,确保在多线程环境下只有一个线程能够成功将state从0改为1。CAS的原子性是通过底层CPU指令保证的,是现代并发编程的基石。
tryRelease方法
tryRelease方法负责释放锁:
protected boolean tryRelease(int releases) {
if (getState() == 0 || !isHeldExclusively()) {
throw new IllegalMonitorStateException();
}
setExclusiveOwnerThread(null);
setState(0);
return true;
}
注意这里释放锁时不需要使用CAS操作,因为只有持有锁的线程才能调用释放方法,不存在竞争条件。
Mutex工作流程详解
让我们通过一个时序图来理解Mutex的完整工作流程:

与ReentrantLock的对比
我们实现的简单Mutex与JDK中的ReentrantLock相比,缺少了几个重要特性:
1. 可重入性
ReentrantLock支持同一个线程多次获取同一把锁,内部通过记录重入次数来实现。而我们的Mutex如果同一个线程连续调用两次lock()会导致死锁。
2. 公平性选项
ReentrantLock提供了公平锁和非公平锁两种模式:
-
公平锁:按照线程请求的顺序分配锁
-
非公平锁:允许插队,可能提高吞吐量
我们的Mutex实现的是非公平锁。
3. 条件变量支持
ReentrantLock可以创建多个Condition对象,实现精细的线程等待/通知机制。
4. 中断处理
ReentrantLock提供了更完善的中断处理机制。
性能优化思考
在实际生产环境中,我们可以基于这个基础版本进行多种优化:
自旋优化
在加入等待队列前,可以让线程短暂自旋,避免线程切换的开销:
// 简化的自旋尝试
for (int i = 0; i < MAX_SPINS; i++) {
if (tryAcquire(1)) {
return;
}
}
// 自旋失败后加入队列
状态预测
可以根据历史数据预测锁的持有时间,决定是否直接入队还是先自旋。
实战应用场景
虽然我们的Mutex功能简单,但在特定场景下仍有应用价值:
-
教学演示:清晰地展示锁的基本原理
-
性能测试基准:作为对比基准测试更复杂锁的性能
-
定制化需求:在某些需要极简实现的场景中使用
总结
通过实现这个简单的Mutex,我们深入理解了AQS的核心工作机制:
-
AQS通过state变量管理同步状态
-
CAS操作保证了状态变更的原子性
-
CLH队列管理等待线程,避免忙等待
-
模板方法模式让使用者只需关注核心逻辑
这个实战例子不仅帮助我们理解了Java并发包的底层原理,更重要的是培养了分析复杂系统时"由简入繁"的思维方式。在后续的学习中,我们可以基于这个基础,逐步理解更复杂的同步器实现。
理解AQS不仅对使用Java并发工具有帮助,更重要的是它提供了一种设计高并发组件的思路和模式,这种思想可以应用到各种编程语言和系统的设计中。
扩展思考
-
如何在这个基础上实现可重入功能?
-
如何实现公平锁版本?
-
如何添加条件变量支持?
-
在分布式环境中,如何实现类似的互斥锁?
这些问题留给读者进一步思考和探索,希望本文能为你的并发编程之旅提供一个坚实的起点。

往期免费源码对应视频:
免费获取--SpringBoot+Vue宠物商城网站系统
🥂(❁´◡`❁)您的点赞👍➕评论📝➕收藏⭐➕关注👀是作者创作的最大动力🤞
💖📕🎉🔥 支持我:点赞👍+收藏⭐️+留言📝+关注👀欢迎留言讨论
🔥🔥🔥(源码 + 调试运行 + 问题答疑)
🔥🔥🔥 有兴趣可以联系我
💖学习知识需费心,
📕整理归纳更费神。
🎉源码免费人人喜,
🔥码农福利等你领!💖常来我家多看看,
📕网址:扣棣编程,
🎉感谢支持常陪伴,
🔥点赞关注别忘记!💖山高路远坑又深,
📕大军纵横任驰奔,
🎉谁敢横刀立马行?
🔥唯有点赞+关注成!
⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇点击此处获取源码⬇⬇⬇⬇⬇⬇⬇⬇⬇
878

被折叠的 条评论
为什么被折叠?



