JVM底层又是如何实现synchronized

本文探讨了JVM中synchronized关键字的底层实现机制,详细解析了其如何保证线程间的同步性和内存可见性。
<think> 嗯,用户想了解synchronized和Lock的底层实现及区别。从用户的问题来看,ta应该有一定的Java并发基础,但可能对底层机制不太清楚。用户引用了四篇资料,内容涵盖了底层原理、性能对比、用法差异等,说明ta需要系统性的解答。 用户可能正在学习Java多线程,或者在工作中遇到了同步问题。ta特意强调"底层实现",说明不满足于表面的API差异,而是想深入理解机制。考虑到synchronized和Lock的重要性,这个问题的确值得深入探讨。 先梳理关键点: synchronized方面要讲清楚对象头Mark Word、Monitor监视器锁、JVM指令三个层次;Lock方面重点说明AQS抽象队列同步器、state状态变量、CAS操作和CLH队列。区别部分需要从六个维度展开:实现层面、锁特性、功能灵活性、性能、死锁处理和锁中断。 注意到引用[3]提到Lock的state变量和可重入机制,这是重点;引用[4]提到的Condition调度机制也需要强调。性能对比要谨慎,因为JDK6之后synchronized优化很大,不能简单说Lock更快。 需要提醒用户场景选择:一般情况用synchronized更简洁,需要超时/中断/公平锁等高级功能时才用Lock。这个实用建议对用户应该很有帮助。 最后考虑设计三个相关问题:原理层面的偏向锁/轻量级锁演进过程,实战层面的死锁排查,以及高级应用的控制策略。这样既能巩固基础,又能拓展应用。 </think> 以下是`synchronized`与`Lock`(以`ReentrantLock`为例)的底层实现及核心区别分析,结合Java内存模型和线程调度机制: --- ### **一、底层实现原理** #### **1. synchronized** - **锁对象结构** 每个Java对象头包含`Mark Word`(存储锁状态标志、线程ID等),锁升级过程: `无锁 → 偏向锁 → 轻量级锁(自旋) → 重量级锁(Monitor)` ```mermaid graph LR A[无锁] -->|首次获取| B[偏向锁] B -->|竞争加剧| C[轻量级锁] C -->|自旋失败| D[重量级锁] ``` - **Monitor机制** 进入同步代码块时,JVM调用`monitorenter`指令关联对象的Monitor: - 每个Monitor包含三个关键字段: - `_owner`:持有锁的线程 - `_EntryList`:阻塞等待锁的线程队列 - `_WaitSet`:调用`wait()`后进入等待状态的线程队列 - 退出时调用`monitorexit`释放锁[^1][^3]。 #### **2. Lock(ReentrantLock)** - **AQS(AbstractQueuedSynchronizer)** 核心是双向CLH队列(FIFO线程等待队列)和`volatile int state`变量: - **加锁流程**: ```java lock() → AQS.acquire() → tryAcquire()(子类实现) 成功:设置state=1,owner=当前线程 失败:线程加入CLH队列阻塞(LockSupport.park()) ``` - **可重入实现**:线程重复获取锁时,`state`累计计数(释放时需匹配次数)[^3][^4]。 - **CAS操作** 通过`Unsafe.compareAndSwapState()`实现`state`的原子更新,避免线程切换开销[^2][^4]。 --- ### **二、核心区别对比** | **特性** | **synchronized** | **Lock(ReentrantLock)** | |------------------|--------------------------------------|-------------------------------------| | **实现层面** | JVM内置(C++实现) | Java API(AQS框架) | | **锁释放** | 自动释放(代码块结束/异常) | 必须手动`unlock()`(防止死锁) | | **中断响应** | 不可中断 | 支持`lockInterruptibly()` | | **公平性** | 非公平锁(默认) | 可选择公平/非公平(构造函数指定) | | **条件队列** | 单一`wait/notify` | 多条件变量(`newCondition()`) | | **超时机制** | 不支持 | `tryLock(long timeout, TimeUnit unit)` | | **性能优化** | JDK6后引入锁升级 | 基于CAS减少内核态切换 | --- ### **三、关键差异详解** 1. **锁调度机制** - synchronized:依赖JVM的`Object.wait()`/`notify()`,随机唤醒等待线程[^4]。 - Lock:通过`Condition.await()`/`signal()`实现精准唤醒(如生产者-消费者模型): ```java Condition notFull = lock.newCondition(); Condition notEmpty = lock.newCondition(); // 生产者线程 notEmpty.signal(); // 唤醒消费者 // 消费者线程 notFull.signal(); // 唤醒生产者 ``` 2. **死锁处理** - Lock可利用`tryLock()`检测死锁并设计回退策略,而synchronized只能重启JVM[^2]。 3. **性能场景** - **低竞争**:synchronized(偏向锁/轻量级锁) > Lock - **高竞争**:Lock(CAS自旋) > synchronized(重量级锁上下文切换)[^1][^4]. --- ### **四、使用建议** - **选择synchronized**:简单同步场景(如单方法同步)、追求代码简洁性。 - **选择Lock**:需要超时控制、可中断锁、公平锁或复杂条件调度(如线程按顺序执行)[^2][^4]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值