为何synchronized使线程呈BLOCKED状态,Lock/信号量则为WAITING?
为什么synchronized等待临界区是BLOCKED,Lock/信号量是WAITING?
核心原因:底层等待机制完全不同
一、synchronized对应的BLOCKED状态
- BLOCKED是JVM专门为内置锁等待设计的状态,只有线程抢占
synchronized锁失败时才会进入。 - 每个被
synchronized修饰的对象都自带一个锁等待队列(Entry Set)。线程抢锁失败后,JVM会自动把它放入这个队列,同时标记线程状态为BLOCKED。 - 当持有锁的线程释放锁时,JVM会直接唤醒队列里的线程,整个等待-唤醒流程由JVM底层自动管控。
二、Lock/信号量对应的WAITING状态
ReentrantLock、Semaphore这类同步工具都是基于**AQS(抽象队列同步器)**实现等待逻辑。- 线程抢占锁/许可失败时,会被加入AQS的等待队列,随后主动调用
LockSupport.park()将自身挂起,此时线程状态变为WAITING(如果是限时等待则为TIMED_WAITING)。 - 这种等待需要显式唤醒:只有当持有锁/许可的线程调用
unlock()(Lock类)或release()(Semaphore类)时,才会触发LockSupport.unpark()唤醒等待队列里的线程,线程被唤醒后才能重新参与竞争。
一句话总结
BLOCKED是JVM为内置锁等待预留的“专属状态”,全程自动管理;WAITING是显式同步工具基于AQS实现的挂起状态,依赖手动触发的唤醒逻辑。
内容的提问来源于stack exchange,提问作者Adarsh Verma
相关产品推荐
相关产品推荐

