[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f1b300lqgtfmoj":3,"$f250wz8h39yydc":8,"$f3e13fn86h0z0l":29,"$f1tmzc20p7l0cb":37,"$fpf26cwx3ji5w":72,"toc-348956544-5-5":76},{"description":4,"domain":5,"id":6,"keywords":4,"title":7},"","api.kongjs.com",1,"默认",[9,20,24],{"children":10,"icon":4,"id":11,"linkType":12,"linkUrl":13,"parentId":14,"sort":15,"status":16,"target":17,"title":18,"visible":19},null,"447369447469600768","URL","\u002F","0",0,"1","_self","首页",true,{"children":10,"icon":4,"id":21,"linkType":12,"linkUrl":22,"parentId":14,"sort":15,"status":16,"target":17,"title":23,"visible":19},"447369693859794944","\u002Fnotes","笔记",{"children":10,"icon":4,"id":25,"linkType":26,"linkUrl":27,"parentId":14,"sort":15,"status":16,"target":17,"title":28,"visible":19},"447369977960976384","PAGE","\u002Fabout","关于我",{"category":30,"categoryId":31,"cover":10,"description":4,"fileId":10,"id":34,"publishAt":10,"tags":35,"title":36},{"articleCount":10,"children":10,"cover":10,"description":4,"fileId":10,"icon":4,"id":31,"parentId":14,"slug":32,"sort":15,"title":33},"453164732518506496","back-end","后端","453165633773772800",[],"Java面试核心知识",[38,41,44,48,52,56,60,64,68],{"children":10,"description":4,"id":39,"noteId":34,"parentId":14,"sort":15,"status":16,"title":40},"453165775620939776","Java基础核心全集（数据类型、拆箱装箱、克隆、对象结构、字符串、包装类、序列化）",{"children":10,"description":4,"id":42,"noteId":34,"parentId":14,"sort":6,"status":16,"title":43},"453166088570544128","JVM原理（JDK8~25）内存结构、分代模型、GC算法、垃圾收集器、元空间、双亲委派机制",{"children":10,"description":4,"id":45,"noteId":34,"parentId":14,"sort":46,"status":16,"title":47},"453166295265845248",2,"Java8至25 对象创建全过程及各版本底层演进差异",{"children":10,"description":4,"id":49,"noteId":34,"parentId":14,"sort":50,"status":16,"title":51},"453166545573519360",3,"Java集合全套原理（List+Map底层、扩容机制、线程安全集合对比）",{"children":10,"description":4,"id":53,"noteId":34,"parentId":14,"sort":54,"status":16,"title":55},"453166809651093504",4,"Java线程原理、六大状态流转、线程结束判断、安全中断、核心方法区别",{"children":10,"description":4,"id":57,"noteId":34,"parentId":14,"sort":58,"status":16,"title":59},"453167023724175360",5,"Java线程池原理、使用规范、常用并发异步工具类",{"children":10,"description":4,"id":61,"noteId":34,"parentId":14,"sort":62,"status":16,"title":63},"453167209447956480",6,"Java 虚拟线程与平台线程：原理、区别与实战使用",{"children":10,"description":4,"id":65,"noteId":34,"parentId":14,"sort":66,"status":16,"title":67},"453167452423987200",7,"CAS与AQS 底层原理、核心流程、面试最全详解",{"children":10,"description":4,"id":69,"noteId":34,"parentId":14,"sort":70,"status":16,"title":71},"453168570885480448",8,"线上服务器CPU飙升 Java代码 完整定位排查流程",{"content":73,"contentType":74,"description":4,"title":67,"wordCount":75},"# CAS与AQS 底层原理、核心流程、面试最全详解\n\nCAS 是**无锁并发基石**（原子操作、乐观锁）；AQS 是 **JUC 并发包核心骨架**（锁、同步器底层父类）。**AQS 底层依赖 CAS 实现加锁**，二者是「基础工具 → 上层框架」的依赖关系，是Java并发面试核心重点。\n\n## 一、CAS 原理（Compare And Swap）\n\n### 1\\. 核心定义\n\n**CAS（比较并交换）**：是一种**无锁、乐观锁、原子操作**。不阻塞线程，通过自旋重试保证并发安全。\n\n核心逻辑三段式（原子执行，不可拆分）：\n\n1. **获取旧值**：读取内存当前值 V\n\n2. **比较校验**：判断 V 是否等于预期值 E\n\n3. **交换更新**：相等则将值更新为新值 N；不相等说明被修改，更新失败，重试\n\n公式：**CAS\\(V,E,N\\)**\n\n### 2\\. 底层实现\n\n- Java 层：`Unsafe` 类的 `compareAndSwapXXX` 本地方法\n\n- JVM 层：汇编指令 **cmpxchg**\n\n- 硬件层：CPU 总线锁\u002F缓存锁保证**硬件级原子性**\n\n**核心优势**：无阻塞、无线程切换、用户态自旋、并发性能远超synchronized重量级锁。\n\n### 3\\. CAS 三大致命问题（面试必考）\n\n#### （1）ABA 问题\n\n场景：线程1读取值A，线程2先改成B、再改回A，线程1CAS比较成功，误以为数据未被修改，导致逻辑异常。\n\n**解决方案**：**版本号机制**（AtomicStampedReference），不仅比较值，还比较版本号。\n\n#### （2）循环自旋开销大\n\n竞争极度激烈时，CAS持续失败、无限自旋，**空转消耗CPU**，导致CPU飙升。\n\n**解决方案**：自适应自旋、超时CAS、退避策略。\n\n#### （3）只能保证单个变量原子性\n\nCAS 仅能原子更新一个变量，无法保证多变量复合操作的原子性。\n\n**解决方案**：使用锁 \u002F AtomicReference 封装对象。\n\n### 4\\. CAS 应用场景\n\n- 所有 Atomic 原子类（AtomicInteger、AtomicLong）\n\n- AQS 锁状态更新、线程入队、抢锁\n\n- 乐观锁、计数器、限流统计\n\n---\n\n## 二、AQS 原理（AbstractQueuedSynchronizer）\n\n**AQS 是 JUC 所有锁和同步工具的底层骨架**。\n\nReentrantLock、CountDownLatch、Semaphore、CyclicBarrier、ThreadPoolExecutor 核心同步逻辑全部基于 AQS 实现。\n\n### 1\\. AQS 三大核心组件\n\n#### （1）state 同步状态（核心变量）\n\n`volatile int state`，通过 CAS 修改，代表锁\u002F资源状态：\n\n- **ReentrantLock**：0=无锁，1=加锁，\\>1=可重入次数\n\n- **CountDownLatch**：代表剩余倒数次数\n\n- **Semaphore**：代表剩余可用信号量数量\n\n#### （2）CLH 双向阻塞队列\n\n抢锁失败的线程，会封装成 Node 节点，**进入队列阻塞排队**，避免CAS无限自旋浪费CPU。\n\n结构：head 头节点 \\+ 无数 Node \\+ tail 尾节点\n\n#### （3）Node 节点\n\n封装阻塞线程、等待状态、前后指针：\n\n- thread：阻塞的线程\n\n- waitStatus：节点等待状态（阻塞、取消、唤醒）\n\n- prev \u002F next：双向链表指针\n\n### 2\\. AQS 核心工作模式\n\nAQS 只定义**排队、阻塞、唤醒、状态更新**通用逻辑，**不定义具体锁逻辑**。\n\n子类（ReentrantLock等）重写：`tryAcquire`、`tryRelease` 实现自己的加锁\u002F释放规则。\n\n### 3\\. AQS 完整抢锁流程（面试必背）\n\n1. **尝试CAS抢锁**：线程通过CAS修改state，成功则直接获取锁，执行业务\n\n2. **抢锁失败入队**：CAS失败，封装为Node节点，CAS入队\n\n3. **前置检查**：判断前驱节点是否有效，是否需要阻塞\n\n4. **LockSupport\\.park\\(\\) 阻塞**：挂起线程，释放CPU，不再自旋\n\n5. **解锁唤醒后继**：持有锁线程释放锁，修改state，唤醒队列中下一个线程\n\n6. **后继线程竞争锁**：被唤醒线程再次CAS尝试抢锁，循环执行\n\n### 4\\. AQS 两种工作模式\n\n#### （1）独占模式（Exclusive）\n\n同一时刻只允许一个线程获取锁。\n\n代表：**ReentrantLock**\n\n#### （2）共享模式（Share）\n\n允许多个线程同时获取资源。\n\n代表：**CountDownLatch、Semaphore、读写锁读模式**\n\n### 5\\. AQS 为什么性能高？\n\n- **无锁抢锁**：成功时直接CAS，不阻塞，速度极快\n\n- **失败才阻塞**：抢不到才park，避免空转浪费CPU\n\n- **队列公平调度**：有序排队、精准唤醒，无无效竞争\n\n- **细粒度控制**：自旋\\+阻塞结合，兼顾高并发与低开销\n\n---\n\n## 三、CAS 与 AQS 核心关系（灵魂考点）\n\n1. **CAS是AQS的底层原子工具**：AQS所有state修改、节点入队全部靠CAS实现线程安全\n\n2. **CAS只负责更新，AQS负责调度**：CAS抢锁失败会无限空转，AQS封装队列\\+阻塞，解决CAS CPU空转问题\n\n3. **互补关系**：CAS负责无锁修改，AQS负责失败排队、线程阻塞唤醒\n\n---\n\n## 四、面试极简背诵版（直接默写）\n\n### CAS 背诵\n\nCAS是比较并交换的硬件级原子乐观锁，通过预期值比对实现无锁更新，性能高；存在ABA问题、CPU自旋空转、仅支持单变量原子操作三大缺陷，ABA可通过版本号解决。\n\n### AQS 背诵\n\nAQS是JUC并发工具底层骨架，核心由state状态、CLH双向队列、Node节点组成。通过CAS尝试抢锁，失败线程入队阻塞，锁释放后唤醒后继线程，实现高效的线程同步，分为独占和共享两种模式。\n\n## 五、高频面试追问\n\n#### 1\\. AQS 和 synchronized 区别？\n\n- synchronized：JVM底层实现，自动加锁释放，阻塞重量级、灵活性低\n\n- AQS\\(Lock\\)：Java代码实现，可中断、可超时、可公平\u002F非公平、可读写分离，性能更优、灵活度更高\n\n#### 2\\. 为什么 AQS 要用 CAS？\n\n保证多线程并发修改 state、入队操作的原子性，不使用重量级锁，保证高并发性能。\n\n#### 3\\. CAS 自旋和 AQS park 区别？\n\n- CAS自旋：用户态循环重试，不释放CPU，高并发耗CPU\n\n- park阻塞：线程挂起，释放CPU，内核态阻塞，无资源消耗\n\n## 六、ReentrantLock 基于 AQS 完整加锁\u002F解锁流程（面试核心）\n\nReentrantLock 是 AQS 独占模式的经典实现，核心特性：**可重入、可公平\u002F非公平、可中断、可超时**。内部通过自定义同步器 `FairSync`（公平锁）、`NonFairSync`（非公平锁）重写 AQS 的 `tryAcquire\u002FtryRelease` 方法，实现加锁释放逻辑。\n\n### 1\\. 核心前置认知\n\n- AQS **state=0**：无锁状态，线程可竞争锁\n\n- AQS **state\\>0**：已加锁，数值代表可重入次数\n\n- **独占模式**：同一时刻仅一个线程持有锁\n\n- 非公平锁：**上来直接抢锁**，不排队，吞吐量高（默认）\n\n- 公平锁：**先判断队列是否有等待线程**，有序竞争，无线程饥饿\n\n### 2\\. 非公平锁 完整加锁流程（默认）\n\n核心特点：不看排队队列，直接CAS抢占锁，效率更高\n\n1. **初始CAS抢锁**：线程调用 lock\\(\\)，直接通过 CAS 尝试将 state 从 0 修改为 1。\n修改成功 → 直接获取锁，设置当前线程为独占持有线程，执行业务逻辑。\n\n2. **抢锁失败，进入 tryAcquire**：CAS 失败说明锁被占用，执行非公平锁的 tryAcquire 逻辑。\n\n3. **判断可重入**：判断当前持有锁的线程是否是自身：\n    是自身：state \\+1，**可重入成功**，直接返回true\n\n4. 不是自身：返回加锁失败\n\n5. **失败入队阻塞**：加锁失败，执行 AQS 核心逻辑：将当前线程封装为 Node 节点，通过 CAS 加入 CLH 阻塞队列。\n\n6. **自旋校验\\+park阻塞**：线程循环判断前驱节点是否为头节点，尝试再次抢锁；多次失败后调用 **LockSupport\\.park\\(\\)** 挂起线程，释放CPU，等待唤醒。\n\n### 3\\. 公平锁 完整加锁流程\n\n核心特点：**严格遵循先来先服务**，杜绝插队，解决线程饥饿\n\n1. **禁止直接插队**：线程调用 lock\\(\\)，不会直接CAS抢锁，优先判断 AQS 等待队列是否存在等待线程。\n\n2. **队列有线程**：直接放弃抢锁，进入队列排队阻塞。\n\n3. **队列无线程**：尝试CAS修改state抢锁。\n\n4. **可重入校验**：抢锁成功则持有锁；失败则判断是否为当前线程重入，是则state累加，否则入队阻塞。\n\n### 4\\. 解锁完整流程（tryRelease）\n\nReentrantLock 解锁**必须层层递减重入次数**，并非一次解锁直接释放\n\n1. **校验持有线程**：解锁线程必须是锁的独占持有线程，否则抛出异常。\n\n2. **重入次数递减**：state 自减 1。\n\n3. **判断是否完全释放**：\n    递减后 **state \\> 0**：代表多次重入，锁未释放，仅返回false\n\n4. 递减后 **state = 0**：锁完全释放，清空独占持有线程\n\n5. **唤醒后继线程**：锁完全释放后，遍历CLH队列，唤醒head节点的下一个有效等待线程。\n\n6. **后继竞争锁**：被唤醒的线程再次通过CAS尝试获取锁，循环执行AQS抢锁逻辑。\n\n### 5\\. 非公平锁 vs 公平锁 核心区别（面试高频）\n\n- **非公平锁（默认）**：上来直接抢锁，允许插队，吞吐量高、性能好，可能导致尾部线程饥饿，生产默认使用。\n\n- **公平锁**：严格排队、无饥饿，线程切换开销大，吞吐量低，适用于对公平性有强要求的业务。\n\n### 6\\. ReentrantLock 可重入原理总结\n\nAQS 的 state 变量记录重入次数，**同一线程每次加锁state\\+1，每次解锁state\\-1**，只有 state 归0才会真正释放锁，完美支持方法嵌套加锁，避免自身死锁。\n\n### 7\\. 面试终极背诵版\n\nReentrantLock基于AQS独占模式实现，默认非公平锁，加锁时先CAS抢占state，成功则持有锁；失败则判断可重入，重入成功累加state，否则线程封装Node入队阻塞。解锁时递减state，归0则释放锁并唤醒队列后继线程。公平锁会优先判断等待队列，禁止插队，保证线程公平竞争。","markdown",4791,{"frontmatter":77,"meta":78,"nodes":194},{},{"title":67,"description":79,"toc":80},"CAS 是无锁并发基石（原子操作、乐观锁）；AQS 是 JUC 并发包核心骨架（锁、同步器底层父类）。AQS 底层依赖 CAS 实现加锁，二者是「基础工具 → 上层框架」的依赖关系，是Java并发面试核心重点。",{"title":4,"searchDepth":58,"depth":58,"links":81},[82,108,144,147,156,169],{"id":83,"depth":46,"text":84,"children":85},"cas-compare-and-swap","一、CAS 原理（Compare And Swap）",[86,89,92,105],{"id":87,"depth":50,"text":88},"cas-compare-and-swap-_1","1. 核心定义",{"id":90,"depth":50,"text":91},"cas-compare-and-swap-_2","2. 底层实现",{"id":93,"depth":50,"text":94,"children":95},"cas-compare-and-swap-_3-cas","3. CAS 三大致命问题（面试必考）",[96,99,102],{"id":97,"depth":54,"text":98},"cas-compare-and-swap-_3-cas-_1aba","（1）ABA 问题",{"id":100,"depth":54,"text":101},"cas-compare-and-swap-_3-cas-_2","（2）循环自旋开销大",{"id":103,"depth":54,"text":104},"cas-compare-and-swap-_3-cas-_3","（3）只能保证单个变量原子性",{"id":106,"depth":50,"text":107},"cas-compare-and-swap-_4-cas","4. CAS 应用场景",{"id":109,"depth":46,"text":110,"children":111},"aqs-abstractqueuedsynchronizer","二、AQS 原理（AbstractQueuedSynchronizer）",[112,125,128,131,141],{"id":113,"depth":50,"text":114,"children":115},"aqs-abstractqueuedsynchronizer-_1-aqs","1. AQS 三大核心组件",[116,119,122],{"id":117,"depth":54,"text":118},"aqs-abstractqueuedsynchronizer-_1-aqs-_1state","（1）state 同步状态（核心变量）",{"id":120,"depth":54,"text":121},"aqs-abstractqueuedsynchronizer-_1-aqs-_2clh","（2）CLH 双向阻塞队列",{"id":123,"depth":54,"text":124},"aqs-abstractqueuedsynchronizer-_1-aqs-_3node","（3）Node 节点",{"id":126,"depth":50,"text":127},"aqs-abstractqueuedsynchronizer-_2-aqs","2. AQS 核心工作模式",{"id":129,"depth":50,"text":130},"aqs-abstractqueuedsynchronizer-_3-aqs","3. AQS 完整抢锁流程（面试必背）",{"id":132,"depth":50,"text":133,"children":134},"aqs-abstractqueuedsynchronizer-_4-aqs","4. AQS 两种工作模式",[135,138],{"id":136,"depth":54,"text":137},"aqs-abstractqueuedsynchronizer-_4-aqs-_1exclusive","（1）独占模式（Exclusive）",{"id":139,"depth":54,"text":140},"aqs-abstractqueuedsynchronizer-_4-aqs-_2share","（2）共享模式（Share）",{"id":142,"depth":50,"text":143},"aqs-abstractqueuedsynchronizer-_5-aqs","5. AQS 为什么性能高？",{"id":145,"depth":46,"text":146},"cas-aqs","三、CAS 与 AQS 核心关系（灵魂考点）",{"id":4,"depth":46,"text":148,"children":149},"四、面试极简背诵版（直接默写）",[150,153],{"id":151,"depth":50,"text":152},"-cas","CAS 背诵",{"id":154,"depth":50,"text":155},"-aqs","AQS 背诵",{"id":157,"depth":46,"text":158,"children":159},"-1","五、高频面试追问",[160,163,166],{"id":161,"depth":54,"text":162},"-_1-aqs-synchronized","1. AQS 和 synchronized 区别？",{"id":164,"depth":54,"text":165},"-_2-aqs-cas","2. 为什么 AQS 要用 CAS？",{"id":167,"depth":54,"text":168},"-_3-cas-aqs-park","3. CAS 自旋和 AQS park 区别？",{"id":170,"depth":46,"text":171,"children":172},"reentrantlock-aqs","六、ReentrantLock 基于 AQS 完整加锁\u002F解锁流程（面试核心）",[173,176,179,182,185,188,191],{"id":174,"depth":50,"text":175},"reentrantlock-aqs-_1","1. 核心前置认知",{"id":177,"depth":50,"text":178},"reentrantlock-aqs-_2","2. 非公平锁 完整加锁流程（默认）",{"id":180,"depth":50,"text":181},"reentrantlock-aqs-_3","3. 公平锁 完整加锁流程",{"id":183,"depth":50,"text":184},"reentrantlock-aqs-_4-tryrelease","4. 解锁完整流程（tryRelease）",{"id":186,"depth":50,"text":187},"reentrantlock-aqs-_5-vs","5. 非公平锁 vs 公平锁 核心区别（面试高频）",{"id":189,"depth":50,"text":190},"reentrantlock-aqs-_6-reentrantlock","6. ReentrantLock 可重入原理总结",{"id":192,"depth":50,"text":193},"reentrantlock-aqs-_7","7. 面试终极背诵版",[195,199,216,219,222,232,235,257,263,265,292,298,300,303,306,316,318,325,330,332,335,340,342,353,356,358,364,367,369,371,377,397,399,406,409,411,414,425,427,437,448,450,488,490,492,495,500,502,505,510,512,538,540,542,562,564,566,568,571,573,576,578,580,588,590,593,595,603,605,624,626,661,663,666,709,711,718,744,746,753,796,798,812,814,821,823],[196,197,67],"h1",{"id":198},"casaqs",[200,201,202,203,207,208,211,212,215],"p",{},"CAS 是",[204,205,206],"strong",{},"无锁并发基石","（原子操作、乐观锁）；AQS 是 ",[204,209,210],{},"JUC 并发包核心骨架","（锁、同步器底层父类）。",[204,213,214],{},"AQS 底层依赖 CAS 实现加锁","，二者是「基础工具 → 上层框架」的依赖关系，是Java并发面试核心重点。",[217,218,84],"h2",{"id":83},[220,221,88],"h3",{"id":87},[200,223,224,227,228,231],{},[204,225,226],{},"CAS（比较并交换）","：是一种",[204,229,230],{},"无锁、乐观锁、原子操作","。不阻塞线程，通过自旋重试保证并发安全。",[200,233,234],{},"核心逻辑三段式（原子执行，不可拆分）：",[236,237,238,245,251],"ol",{},[239,240,241,244],"li",{},[204,242,243],{},"获取旧值","：读取内存当前值 V",[239,246,247,250],{},[204,248,249],{},"比较校验","：判断 V 是否等于预期值 E",[239,252,253,256],{},[204,254,255],{},"交换更新","：相等则将值更新为新值 N；不相等说明被修改，更新失败，重试",[200,258,259,260],{},"公式：",[204,261,262],{},"CAS(V,E,N)",[220,264,91],{"id":90},[266,267,268,280,286],"ul",{},[239,269,270,271,275,276,279],{},"Java 层：",[272,273,274],"code",{},"Unsafe"," 类的 ",[272,277,278],{},"compareAndSwapXXX"," 本地方法",[239,281,282,283],{},"JVM 层：汇编指令 ",[204,284,285],{},"cmpxchg",[239,287,288,289],{},"硬件层：CPU 总线锁\u002F缓存锁保证",[204,290,291],{},"硬件级原子性",[200,293,294,297],{},[204,295,296],{},"核心优势","：无阻塞、无线程切换、用户态自旋、并发性能远超synchronized重量级锁。",[220,299,94],{"id":93},[301,302,98],"h4",{"id":97},[200,304,305],{},"场景：线程1读取值A，线程2先改成B、再改回A，线程1CAS比较成功，误以为数据未被修改，导致逻辑异常。",[200,307,308,311,312,315],{},[204,309,310],{},"解决方案","：",[204,313,314],{},"版本号机制","（AtomicStampedReference），不仅比较值，还比较版本号。",[301,317,101],{"id":100},[200,319,320,321,324],{},"竞争极度激烈时，CAS持续失败、无限自旋，",[204,322,323],{},"空转消耗CPU","，导致CPU飙升。",[200,326,327,329],{},[204,328,310],{},"：自适应自旋、超时CAS、退避策略。",[301,331,104],{"id":103},[200,333,334],{},"CAS 仅能原子更新一个变量，无法保证多变量复合操作的原子性。",[200,336,337,339],{},[204,338,310],{},"：使用锁 \u002F AtomicReference 封装对象。",[220,341,107],{"id":106},[266,343,344,347,350],{},[239,345,346],{},"所有 Atomic 原子类（AtomicInteger、AtomicLong）",[239,348,349],{},"AQS 锁状态更新、线程入队、抢锁",[239,351,352],{},"乐观锁、计数器、限流统计",[354,355],"hr",{},[217,357,110],{"id":109},[200,359,360,363],{},[204,361,362],{},"AQS 是 JUC 所有锁和同步工具的底层骨架","。",[200,365,366],{},"ReentrantLock、CountDownLatch、Semaphore、CyclicBarrier、ThreadPoolExecutor 核心同步逻辑全部基于 AQS 实现。",[220,368,114],{"id":113},[301,370,118],{"id":117},[200,372,373,376],{},[272,374,375],{},"volatile int state","，通过 CAS 修改，代表锁\u002F资源状态：",[266,378,379,385,391],{},[239,380,381,384],{},[204,382,383],{},"ReentrantLock","：0=无锁，1=加锁，>1=可重入次数",[239,386,387,390],{},[204,388,389],{},"CountDownLatch","：代表剩余倒数次数",[239,392,393,396],{},[204,394,395],{},"Semaphore","：代表剩余可用信号量数量",[301,398,121],{"id":120},[200,400,401,402,405],{},"抢锁失败的线程，会封装成 Node 节点，",[204,403,404],{},"进入队列阻塞排队","，避免CAS无限自旋浪费CPU。",[200,407,408],{},"结构：head 头节点 + 无数 Node + tail 尾节点",[301,410,124],{"id":123},[200,412,413],{},"封装阻塞线程、等待状态、前后指针：",[266,415,416,419,422],{},[239,417,418],{},"thread：阻塞的线程",[239,420,421],{},"waitStatus：节点等待状态（阻塞、取消、唤醒）",[239,423,424],{},"prev \u002F next：双向链表指针",[220,426,127],{"id":126},[200,428,429,430,433,434,363],{},"AQS 只定义",[204,431,432],{},"排队、阻塞、唤醒、状态更新","通用逻辑，",[204,435,436],{},"不定义具体锁逻辑",[200,438,439,440,443,444,447],{},"子类（ReentrantLock等）重写：",[272,441,442],{},"tryAcquire","、",[272,445,446],{},"tryRelease"," 实现自己的加锁\u002F释放规则。",[220,449,130],{"id":129},[236,451,452,458,464,470,476,482],{},[239,453,454,457],{},[204,455,456],{},"尝试CAS抢锁","：线程通过CAS修改state，成功则直接获取锁，执行业务",[239,459,460,463],{},[204,461,462],{},"抢锁失败入队","：CAS失败，封装为Node节点，CAS入队",[239,465,466,469],{},[204,467,468],{},"前置检查","：判断前驱节点是否有效，是否需要阻塞",[239,471,472,475],{},[204,473,474],{},"LockSupport.park() 阻塞","：挂起线程，释放CPU，不再自旋",[239,477,478,481],{},[204,479,480],{},"解锁唤醒后继","：持有锁线程释放锁，修改state，唤醒队列中下一个线程",[239,483,484,487],{},[204,485,486],{},"后继线程竞争锁","：被唤醒线程再次CAS尝试抢锁，循环执行",[220,489,133],{"id":132},[301,491,137],{"id":136},[200,493,494],{},"同一时刻只允许一个线程获取锁。",[200,496,497,498],{},"代表：",[204,499,383],{},[301,501,140],{"id":139},[200,503,504],{},"允许多个线程同时获取资源。",[200,506,497,507],{},[204,508,509],{},"CountDownLatch、Semaphore、读写锁读模式",[220,511,143],{"id":142},[266,513,514,520,526,532],{},[239,515,516,519],{},[204,517,518],{},"无锁抢锁","：成功时直接CAS，不阻塞，速度极快",[239,521,522,525],{},[204,523,524],{},"失败才阻塞","：抢不到才park，避免空转浪费CPU",[239,527,528,531],{},[204,529,530],{},"队列公平调度","：有序排队、精准唤醒，无无效竞争",[239,533,534,537],{},[204,535,536],{},"细粒度控制","：自旋+阻塞结合，兼顾高并发与低开销",[354,539],{},[217,541,146],{"id":145},[236,543,544,550,556],{},[239,545,546,549],{},[204,547,548],{},"CAS是AQS的底层原子工具","：AQS所有state修改、节点入队全部靠CAS实现线程安全",[239,551,552,555],{},[204,553,554],{},"CAS只负责更新，AQS负责调度","：CAS抢锁失败会无限空转，AQS封装队列+阻塞，解决CAS CPU空转问题",[239,557,558,561],{},[204,559,560],{},"互补关系","：CAS负责无锁修改，AQS负责失败排队、线程阻塞唤醒",[354,563],{},[217,565,148],{"id":4},[220,567,152],{"id":151},[200,569,570],{},"CAS是比较并交换的硬件级原子乐观锁，通过预期值比对实现无锁更新，性能高；存在ABA问题、CPU自旋空转、仅支持单变量原子操作三大缺陷，ABA可通过版本号解决。",[220,572,155],{"id":154},[200,574,575],{},"AQS是JUC并发工具底层骨架，核心由state状态、CLH双向队列、Node节点组成。通过CAS尝试抢锁，失败线程入队阻塞，锁释放后唤醒后继线程，实现高效的线程同步，分为独占和共享两种模式。",[217,577,158],{"id":157},[301,579,162],{"id":161},[266,581,582,585],{},[239,583,584],{},"synchronized：JVM底层实现，自动加锁释放，阻塞重量级、灵活性低",[239,586,587],{},"AQS(Lock)：Java代码实现，可中断、可超时、可公平\u002F非公平、可读写分离，性能更优、灵活度更高",[301,589,165],{"id":164},[200,591,592],{},"保证多线程并发修改 state、入队操作的原子性，不使用重量级锁，保证高并发性能。",[301,594,168],{"id":167},[266,596,597,600],{},[239,598,599],{},"CAS自旋：用户态循环重试，不释放CPU，高并发耗CPU",[239,601,602],{},"park阻塞：线程挂起，释放CPU，内核态阻塞，无资源消耗",[217,604,171],{"id":170},[200,606,607,608,611,612,615,616,619,620,623],{},"ReentrantLock 是 AQS 独占模式的经典实现，核心特性：",[204,609,610],{},"可重入、可公平\u002F非公平、可中断、可超时","。内部通过自定义同步器 ",[272,613,614],{},"FairSync","（公平锁）、",[272,617,618],{},"NonFairSync","（非公平锁）重写 AQS 的 ",[272,621,622],{},"tryAcquire\u002FtryRelease"," 方法，实现加锁释放逻辑。",[220,625,175],{"id":174},[266,627,628,635,641,647,654],{},[239,629,630,631,634],{},"AQS ",[204,632,633],{},"state=0","：无锁状态，线程可竞争锁",[239,636,630,637,640],{},[204,638,639],{},"state>0","：已加锁，数值代表可重入次数",[239,642,643,646],{},[204,644,645],{},"独占模式","：同一时刻仅一个线程持有锁",[239,648,649,650,653],{},"非公平锁：",[204,651,652],{},"上来直接抢锁","，不排队，吞吐量高（默认）",[239,655,656,657,660],{},"公平锁：",[204,658,659],{},"先判断队列是否有等待线程","，有序竞争，无线程饥饿",[220,662,178],{"id":177},[200,664,665],{},"核心特点：不看排队队列，直接CAS抢占锁，效率更高",[236,667,668,674,680,690,693,699],{},[239,669,670,673],{},[204,671,672],{},"初始CAS抢锁","：线程调用 lock()，直接通过 CAS 尝试将 state 从 0 修改为 1。\n修改成功 → 直接获取锁，设置当前线程为独占持有线程，执行业务逻辑。",[239,675,676,679],{},[204,677,678],{},"抢锁失败，进入 tryAcquire","：CAS 失败说明锁被占用，执行非公平锁的 tryAcquire 逻辑。",[239,681,682,685,686,689],{},[204,683,684],{},"判断可重入","：判断当前持有锁的线程是否是自身：\n是自身：state +1，",[204,687,688],{},"可重入成功","，直接返回true",[239,691,692],{},"不是自身：返回加锁失败",[239,694,695,698],{},[204,696,697],{},"失败入队阻塞","：加锁失败，执行 AQS 核心逻辑：将当前线程封装为 Node 节点，通过 CAS 加入 CLH 阻塞队列。",[239,700,701,704,705,708],{},[204,702,703],{},"自旋校验+park阻塞","：线程循环判断前驱节点是否为头节点，尝试再次抢锁；多次失败后调用 ",[204,706,707],{},"LockSupport.park()"," 挂起线程，释放CPU，等待唤醒。",[220,710,181],{"id":180},[200,712,713,714,717],{},"核心特点：",[204,715,716],{},"严格遵循先来先服务","，杜绝插队，解决线程饥饿",[236,719,720,726,732,738],{},[239,721,722,725],{},[204,723,724],{},"禁止直接插队","：线程调用 lock()，不会直接CAS抢锁，优先判断 AQS 等待队列是否存在等待线程。",[239,727,728,731],{},[204,729,730],{},"队列有线程","：直接放弃抢锁，进入队列排队阻塞。",[239,733,734,737],{},[204,735,736],{},"队列无线程","：尝试CAS修改state抢锁。",[239,739,740,743],{},[204,741,742],{},"可重入校验","：抢锁成功则持有锁；失败则判断是否为当前线程重入，是则state累加，否则入队阻塞。",[220,745,184],{"id":183},[200,747,748,749,752],{},"ReentrantLock 解锁",[204,750,751],{},"必须层层递减重入次数","，并非一次解锁直接释放",[236,754,755,761,767,777,784,790],{},[239,756,757,760],{},[204,758,759],{},"校验持有线程","：解锁线程必须是锁的独占持有线程，否则抛出异常。",[239,762,763,766],{},[204,764,765],{},"重入次数递减","：state 自减 1。",[239,768,769,772,773,776],{},[204,770,771],{},"判断是否完全释放","：\n递减后 ",[204,774,775],{},"state > 0","：代表多次重入，锁未释放，仅返回false",[239,778,779,780,783],{},"递减后 ",[204,781,782],{},"state = 0","：锁完全释放，清空独占持有线程",[239,785,786,789],{},[204,787,788],{},"唤醒后继线程","：锁完全释放后，遍历CLH队列，唤醒head节点的下一个有效等待线程。",[239,791,792,795],{},[204,793,794],{},"后继竞争锁","：被唤醒的线程再次通过CAS尝试获取锁，循环执行AQS抢锁逻辑。",[220,797,187],{"id":186},[266,799,800,806],{},[239,801,802,805],{},[204,803,804],{},"非公平锁（默认）","：上来直接抢锁，允许插队，吞吐量高、性能好，可能导致尾部线程饥饿，生产默认使用。",[239,807,808,811],{},[204,809,810],{},"公平锁","：严格排队、无饥饿，线程切换开销大，吞吐量低，适用于对公平性有强要求的业务。",[220,813,190],{"id":189},[200,815,816,817,820],{},"AQS 的 state 变量记录重入次数，",[204,818,819],{},"同一线程每次加锁state+1，每次解锁state-1","，只有 state 归0才会真正释放锁，完美支持方法嵌套加锁，避免自身死锁。",[220,822,193],{"id":192},[200,824,825],{},"ReentrantLock基于AQS独占模式实现，默认非公平锁，加锁时先CAS抢占state，成功则持有锁；失败则判断可重入，重入成功累加state，否则线程封装Node入队阻塞。解锁时递减state，归0则释放锁并唤醒队列后继线程。公平锁会优先判断等待队列，禁止插队，保证线程公平竞争。"]