Java的synchronized方法/语句、ReentrantLock等锁是否属于忙等待机制?
关于Java同步锁机制的相关问题解答
1. synchronized、ReentrantLock是否属于忙等待机制
- 三类同步机制默认都不属于忙等待。忙等待的核心特征是线程未获取到锁时持续占用CPU循环检查锁状态,不会让出执行权;而这三类锁的线程抢锁失败后,默认会进入阻塞状态,释放CPU资源,不会出现无意义的CPU空耗。
- 补充:仅在锁竞争不激烈的场景下,synchronized的轻量级锁阶段、ReentrantLock的抢锁逻辑会有极短次数的自旋重试(属于有限次的临时优化),如果重试失败仍会进入阻塞,不属于典型的忙等待机制。
2. 等待线程的通知机制
- synchronized方法/同步块:基于JVM内置的对象监视器(Monitor)实现。每个Java对象都对应一个Monitor结构,抢锁失败的线程会被放入Monitor的入口等待队列阻塞挂起。当持有锁的线程执行完同步逻辑、主动释放锁时,JVM会从等待队列中唤醒一个或多个阻塞线程,重新参与锁竞争。
- ReentrantLock:基于
AbstractQueuedSynchronizer(AQS)实现。抢锁失败的线程会被封装成队列节点,放入AQS的双向同步队列中,通过LockSupport.park()挂起。持有锁的线程释放锁时,会主动调用LockSupport.unpark()唤醒队列中排队的后继线程,被唤醒的线程即可再次尝试抢锁。
3. 底层是否基于Semaphore实现
- 两类锁的底层实现都和Semaphore无关:
- synchronized是JVM层内置的同步机制,HotSpot虚拟机中实现了偏向锁、轻量级锁、重量级锁的锁升级流程,依赖对象头的Mark Word、操作系统的互斥量(Mutex)实现,和Semaphore没有关联。
- ReentrantLock和Semaphore同属于JDK层面的同步工具类,二者都是基于AQS实现的平级组件,不存在谁依赖谁的关系。Semaphore是通过AQS维护许可数实现限流,ReentrantLock是通过AQS维护锁持有状态、重入计数实现独占锁,二者底层逻辑完全独立。
相关代码示例(修正拼写错误后)
// 同步实例方法,锁对象为当前类实例this public synchronized void method(){} // 同步块,自定义锁对象 synchronized (object) {} // ReentrantLock加锁 ReentrantLock reentrantLock = new ReentrantLock(); reentrantLock.lock();
内容的提问来源于stack exchange,提问作者Rajat Aggarwal
相关产品推荐
相关产品推荐

