对象锁通过改变线程状态间接影响调度:争锁失败使线程进入BLOCKED态被调度器忽略;sleep()持有锁但休眠,wait()释放锁并入WaitSet,才允许其他线程竞争;synchronized不保证公平性,调度取决于RUNNABLE线程集合与系统策略;Monitor的Owner、EntryList和WaitSet协同实现状态转换与调度可见性。

对象锁本身不直接干预线程调度器的决策逻辑,但它通过改变线程的状态和竞争关系,间接影响调度行为。
锁导致线程进入阻塞状态,调度器跳过它
当一个线程尝试获取已被占用的对象锁(例如进入 synchronized 代码块或方法),而锁正被其他线程持有时,该线程会立即进入 BLOCKED 状态。此时 JVM 调度器不会将 CPU 时间片分配给它——调度器只在 RUNNABLE 状态的线程中选择执行目标。也就是说,锁争用把“想运行但没资源”的线程主动踢出调度队列,直到锁被释放、线程被唤醒并重新变为 RUNNABLE。
持有锁的线程即使休眠,也不让出锁
这点容易被误解:如果一个线程持有对象锁后调用 Thread.sleep() 或 wait(),行为完全不同:
-
sleep():线程进入 TIMED_WAITING,但继续持有锁,其他线程仍无法获取该锁,调度器照常可能调度其他 RUNNABLE 线程,但锁资源被“占着不动”; -
wait():线程释放锁、进入 WAITING,并加入对象的 WaitSet;此时锁空出,其他线程才有机会竞争并获得它——这才是真正让调度器有机会切换执行权的关键动作。
锁粒度与调度公平性没有必然联系
Java 的 synchronized 锁不保证公平性(即不按等待顺序分配)。多个线程在 EntryList 中等待同一把锁时,谁被唤醒由 JVM 实现决定,与线程优先级、等待时长都无关。这意味着:
立即学习“Java免费学习笔记(深入)”;
- 高优先级线程在锁等待队列里,不一定比低优先级线程先拿到锁;
- 调度器选中哪个 RUNNABLE 线程执行,和它是否“刚被 notify”或“等最久”没有绑定关系;
- 真正影响调度结果的是:哪些线程处于 RUNNABLE 状态 + 操作系统/CPU 的实际调度策略。
Monitor 结构是调度协同的底层桥梁
每个对象关联的 Monitor 包含 Owner、EntryList 和 WaitSet 三个部分。调度器虽不直接读取这些结构,但 JVM 内部通过它们协调线程状态转换:
- Owner 非空 → 其他线程进 EntryList → 调度器看不到它们;
- Owner 调用 wait() → 移入 WaitSet 并释放锁 → EntryList 中某线程被选为新 Owner → 它变成 RUNNABLE → 调度器下次可能选中它;
- notify/notifyAll 不唤醒线程本身,只是将其从 WaitSet 移到 EntryList 或直接设为 Owner(取决于实现)→ 状态变更后才影响调度可见性。


















