为何Java采用AQS而非直接使用操作系统原生mutex实现同步?
AQS相比操作系统原生mutex的优势及Java自研原因
核心优势
- 更低的无冲突场景开销
操作系统提供的mutex属于内核态资源,每次加锁、解锁操作都需要完成用户态到内核态的上下文切换,单次切换开销在数百个CPU时钟周期左右,在锁竞争不激烈的场景下,切换成本远高于锁操作本身。而AQS是纯用户态实现的同步框架,优先通过CAS自旋尝试获取锁,只有多次自旋失败才会将线程挂起进入阻塞状态,大幅减少了无意义的内核态切换,低冲突场景下性能比原生mutex高一个数量级。 - 更灵活的同步能力支持
原生mutex的功能非常单一,仅能实现最基础的互斥同步逻辑。而AQS作为通用同步器框架,同时支持互斥模式、共享模式两种同步逻辑,可快速扩展实现可重入锁、公平/非公平锁、读写锁、CountDownLatch、Semaphore、CyclicBarrier等几十种不同特性的同步组件,一套队列调度逻辑可以全量复用,不需要为每种同步工具单独对接内核API。 - 更高的JVM可控性
原生mutex的状态、等待队列完全由内核维护,JVM无法直接干预,无法实现JDK中大量的锁优化逻辑:比如偏向锁、轻量级锁、锁消除、锁粗化等优化手段,都依赖Java层可控的锁状态实现,原生mutex完全不支持这类定制优化。同时AQS的实现完全屏蔽了不同操作系统的mutex API差异,大幅降低了JVM的跨平台适配成本,也能更灵活的实现超时拿锁、响应中断等上层特性。 - 更少的资源限制
原生mutex属于系统内核资源,单节点可创建的数量有明确上限,Java应用如果大量创建同步锁很容易耗尽系统资源。而AQS本质是JVM堆中的普通Java对象,只要堆内存足够就可以无限制创建,不会占用额外的内核资源。
内容的提问来源于stack exchange,提问作者choxsword
相关产品推荐
相关产品推荐

