[{"data":1,"prerenderedAt":233},["ShallowReactive",2],{"blog-java-concurrent":3},{"id":4,"title":5,"body":6,"category":219,"date":220,"description":221,"extension":222,"meta":223,"navigation":224,"path":225,"seo":226,"stem":227,"tags":228,"__hash__":232},"blog\u002Fblog\u002Fjava-concurrent.md","Java并发编程演进：从悲观锁的妥协到 AQS 的优雅",{"type":7,"value":8,"toc":211},"minimark",[9,13,22,27,39,46,62,72,76,90,97,102,105,124,148,153,157,166,184,194,197,204],[10,11,5],"h1",{"id":12},"java并发编程演进从悲观锁的妥协到-aqs-的优雅",[14,15,16,17,21],"p",{},"在复杂的高并发业务场景中，多线程编程的核心本质只有一个：",[18,19,20],"strong",{},"如何安全、高效地管理共享状态","。从早期粗暴的重量级锁，到后来精细化的并发包（JUC），Java 在并发控制上的演进，是一部不断在“上下文切换开销”与“数据一致性”之间寻找平衡的历史。",[23,24,26],"h2",{"id":25},"_1-synchronized-的涅槃从性能杀手到自适应","1. synchronized 的涅槃：从“性能杀手”到自适应",[14,28,29,30,34,35,38],{},"早期的 Java 开发中，",[31,32,33],"code",{},"synchronized"," 常常被视作性能杀手。因为在 JDK 1.6 之前，它是一个纯粹的",[18,36,37],{},"重量级锁","。每次线程竞争失败，都会直接陷入操作系统级别的阻塞（Mutex Lock），这种从用户态到内核态的频繁切换，其开销往往比执行同步代码本身还要大得多。",[14,40,41,42,45],{},"但这并不意味着我们要抛弃语言层面的关键字。JVM 团队在后续版本中引入了",[18,43,44],{},"锁升级机制","（无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁）。",[47,48,49,56],"ul",{},[50,51,52,55],"li",{},[18,53,54],{},"偏向锁（Biased Locking）："," 在绝大多数情况下，锁不仅不存在多线程竞争，甚至总是由同一个线程多次获得。偏向锁通过在对象头中记录线程 ID，让该线程后续连 CAS 操作都不需要就能直接进入同步块。",[50,57,58,61],{},[18,59,60],{},"轻量级锁（自旋锁）："," 当有第二个线程来竞争时，升级为轻量级锁。由于很多同步块的执行时间极短，让等待的线程在 CPU 上“空跑”一会（自旋），反而比挂起线程更高效。",[14,63,64,67,68,71],{},[18,65,66],{},"小结："," 技术的优化往往遵循“二八定律”。JVM 锁升级的底层哲学是：",[18,69,70],{},"永远假设最好的情况，并在情况恶化时提供兜底方案","。它避免了过早悲观带来的沉重系统开销。",[23,73,75],{"id":74},"_2-突破-jvm-限制juc-的基石-aqs","2. 突破 JVM 限制：JUC 的基石 AQS",[14,77,78,79,81,82,85,86,89],{},"如果 ",[31,80,33],{}," 已经足够优化，为什么 Doug Lea 还要在 ",[31,83,84],{},"java.util.concurrent"," 包中写一套基于 ",[31,87,88],{},"ReentrantLock"," 的锁机制？",[14,91,92,93,96],{},"答案是：",[18,94,95],{},"极致的灵活性与功能扩展","。",[14,98,99,101],{},[31,100,33],{}," 的加锁和释放是隐式的，且不支持中断响应、超时尝试以及公平锁。为了实现这些高级特性，JUC 引入了 AQS（AbstractQueuedSynchronizer）。",[14,103,104],{},"AQS 的核心设计极其优雅，它仅仅使用了两样东西就构建了整个并发包的基石：",[106,107,108,118],"ol",{},[50,109,110,117],{},[18,111,112,113,116],{},"一个 volatile 的 ",[31,114,115],{},"state"," 变量："," 用于表示当前的同步状态（例如，被锁定了几次，或者信号量还剩多少）。",[50,119,120,123],{},[18,121,122],{},"一个 FIFO 的双向链表（CLH 队列）："," 用于存储排队等待获取锁的线程。",[14,125,126,127,129,130,129,133,136,137,140,141,144,145,147],{},"所有基于 AQS 的同步器（如 ",[31,128,88],{},"、",[31,131,132],{},"Semaphore",[31,134,135],{},"CountDownLatch","），只是在重写 ",[31,138,139],{},"tryAcquire"," 和 ",[31,142,143],{},"tryRelease"," 方法，定义自己如何操作这个 ",[31,146,115],{},"，而繁琐的线程排队、阻塞、唤醒工作，AQS 已经在底层统一处理了。",[14,149,150,152],{},[18,151,66],{}," AQS 的设计是面向对象框架设计的典范。它将“状态管理”开放给子类，将“线程调度”封装在底层，用极简的数据结构解决了复杂的并发协同问题。",[23,154,156],{"id":155},"_3-锁的尽头是无锁cas-与并发哲学","3. 锁的尽头是无锁：CAS 与并发哲学",[14,158,159,160,162,163,165],{},"无论是 ",[31,161,33],{}," 还是 ",[31,164,88],{},"，本质上依然是悲观锁——“我认为别人会修改数据，所以我先锁上”。而在读多写少的极高并发场景下，悲观锁的排队机制会成为吞吐量的绝对瓶颈。",[14,167,168,169,172,173,176,177,180,181,96],{},"此时，基于硬件指令支持的 CAS（Compare-And-Swap）成为了突破口。配合 ",[31,170,171],{},"volatile"," 保证的可见性，Java 提供了 ",[31,174,175],{},"Atomic"," 系列类和更高级的 ",[31,178,179],{},"LongAdder","。它们采用乐观锁的哲学：",[18,182,183],{},"我不加锁，我只在更新的最后一刻检查数据有没有被别人动过",[14,185,186,187,189,190,193],{},"当然，CAS 也带来了 ABA 问题和高竞争下的 CPU 自旋消耗（空耗 CPU）。",[31,188,179],{}," 的出现正是为了解决 CAS 的自旋热点问题，它通过将单一的 value 拆分成一个数组（Cell",[191,192],"span",{},"），让多线程把竞争分散到不同的内存块上，最后再求和，完美诠释了“空间换时间”的并发之道。",[23,195,196],{"id":196},"总结",[14,198,199,200,203],{},"Java 并发控制的演进，其实是一条",[18,201,202],{},"逐渐将调度权从操作系统内核态收回到用户态","的路径。从依赖 OS 的互斥量，到 JVM 内部的锁升级，再到纯 Java 代码实现的 AQS 队列与 CAS 无锁化设计。在进行架构选型时，没有绝对最好的锁，只有最契合当前业务读写比例、竞争激烈程度的权衡策略。",[14,205,206],{},[207,208,210],"a",{"href":209},"\u002Fblog\u002F","返回博客列表",{"title":212,"searchDepth":213,"depth":213,"links":214},"",2,[215,216,217,218],{"id":25,"depth":213,"text":26},{"id":74,"depth":213,"text":75},{"id":155,"depth":213,"text":156},{"id":196,"depth":213,"text":196},"Java并发","2026-03-15","在复杂的高并发业务场景中，多线程编程的核心本质只有一个：如何安全、高效地管理共享状态。从早期粗暴的重量级锁，到后来精细化的并发包（JUC），Java 在并发控制上的演进，是一部不断在“上下文切换开销”与“数据一致性”之间寻找平衡的历史。","md",{},true,"\u002Fblog\u002Fjava-concurrent",{"title":5,"description":221},"blog\u002Fjava-concurrent",[229,230,231],"并发编程","AQS","锁机制","y_auBKHRElAqxnNmRO--Dy2Jmq6lrcS3I9YLFksJaJ4",1779959653037]