欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > Java 并发包核心机制深度解析:锁的公平性、异步调度、AQS 原理全解

Java 并发包核心机制深度解析:锁的公平性、异步调度、AQS 原理全解

2025/4/22 15:11:58 来源:https://blog.csdn.net/weixin_39863120/article/details/147403507  浏览:    关键词:Java 并发包核心机制深度解析:锁的公平性、异步调度、AQS 原理全解

🧠 Java 并发包核心机制深度解析:锁的公平性、异步调度、AQS 原理全解

Java 并发编程的地基是 java.util.concurrent,但真正驱动这个系统的,是它背后隐藏的三根支柱:

  • ReentrantLock 的公平/非公平调度策略
  • CompletableFuture 的异步执行模型
  • AQS 的队列与阻塞线程管理机制

本文将以源码 & 结构视角解析这三块知识点,并配图讲清它们的运行状态与机制。


🔐 ReentrantLock 公平锁 vs 非公平锁

✳️ 概念区别

  • 公平锁(Fair):排队等待的线程会按顺序获取锁,避免“插队”。
  • 非公平锁(NonFair):新线程尝试直接 CAS 获取锁,如果成功就跳过队列 —— 提升吞吐量,但可能导致“饿死”。

📜 构造方式

// 默认是非公平锁
Lock lock = new ReentrantLock(); // 公平锁
Lock fairLock = new ReentrantLock(true);

⚙️ 实现原理

ReentrantLock 继承自 AbstractQueuedSynchronizer(AQS),关键方法如下:

// 非公平:直接尝试 CAS 抢锁
final boolean nonfairTryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0 && compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}return false;
}// 公平:要先检查前面有没有排队线程
final boolean tryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {if (!hasQueuedPredecessors() &&compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}return false;
}

🔁 锁状态图

[Free Lock] → tryAcquire()↓       ↘ (被占用)
[Acquired]   → 加入 AQS 等待队列 → LockSupport.park() 阻塞↓unlock() → 唤醒队列中的下一个线程

🚀 CompletableFuture 的异步调度机制

CompletableFuture 是 JDK 8 提供的函数式异步编程工具,常用于构建任务链和异步合并。

🧱 内部结构

CompletableFuture<T> {Object result;volatile Completion stack; // 任务链
}

每一个 thenApply, thenAccept, thenCombine 等方法,本质上是构建一个任务节点(Completion),放入队列中。

🔧 异步调度流程

CompletableFuture.supplyAsync(() -> {return 42;
}).thenApplyAsync(res -> {return res + 1;
});
  1. supplyAsync() 提交任务到默认线程池(ForkJoinPool.commonPool)
  2. 任务执行完成后,触发 postComplete(),依次唤醒后续 Completion
  3. 后续任务如果带 Async,会再次提交到线程池执行,否则同步调用

☑️ 核心调度代码

private void postComplete() {Completion h;while ((h = stack) != null) {if (UNSAFE.compareAndSwapObject(this, STACK, h, null))h.tryFire(NESTED);}
}

Completion 是内部静态类,代表任务节点链表,构成任务依赖树。


🧱 AQS:并发核心队列结构

AbstractQueuedSynchronizer 是整个 locks同步器 的基石,核心是管理同步状态与阻塞线程。

🧬 AQS 结构图

+-----------------------+
|     AbstractQueuedSynchronizer     |
+-----------------------+
| int state                          |
| Node head                          |
| Node tail                          |
+-----------------------+Node {Thread thread;Node next;Node prev;int waitStatus;  // SIGNAL, CANCELLED...
}

🔁 加锁过程(独占)

  1. 尝试获取锁(CAS 设置 state)
  2. 失败则入队(构造 Node,放入队列)
  3. 阻塞线程(LockSupport.park)
  4. 被唤醒后再次尝试获取锁

✨ 解锁过程

  1. CAS 修改 state,释放锁
  2. 唤醒队列中第一个 SIGNAL 状态的 Node(即下一个等待线程)
  3. 线程继续执行

🎯 总结:三者协作关系

模块角色底层依赖
ReentrantLock负责线程互斥、资源保护AQS + LockSupport
CompletableFuture异步任务链式调度ForkJoinPool + Completion
AQS管理线程队列、状态、阻塞机制CAS + LockSupport + Unsafe

## 🧩 附图:Java 并发包知识导图

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词