java中object类锁机制本质是synchronized的底层监视器(monitor),wait/notify必须在synchronized块中调用,因需持有对象锁才能操作其monitor;wait释放锁并进入waiting状态,notify随机唤醒一个等待线程,notifyall唤醒全部等待线程。

Java 中的 Object 类锁机制,本质上就是 synchronized 锁的底层载体——每个 Java 对象都有一个与之关联的监视器(monitor),而这个 monitor 的入口就体现在 Object 类提供的 wait()、notify()、notifyAll() 等方法上。面试时问“Object 类锁机制”,实际是在考察你对 synchronized、对象监视器、线程通信三者关系的理解是否扎实。
Object 的 wait/notify 为什么必须在 synchronized 块中调用
因为这些方法操作的是对象内部的 monitor(监视器),而只有持有该对象锁的线程才能进入 monitor 并执行相关操作。JVM 在运行时会校验当前线程是否是 monitor 的拥有者,不是则抛出 IllegalMonitorStateException。
- wait():释放当前持有的对象锁,并让线程进入 WAITING 状态,直到被 notify 或中断
- notify():唤醒一个正在该对象上 wait 的线程(不保证唤醒哪一个)
- notifyAll():唤醒所有在该对象上 wait 的线程,由调度器决定谁先抢到锁
synchronized 锁的对象到底是哪个
取决于 synchronized 的写法:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
synchronized(this)或synchronized(非static方法)→ 锁的是当前实例对象(即 this) -
synchronized(任意对象引用)→ 锁的是括号里那个对象实例 -
synchronized(静态方法)或synchronized(类.class)→ 锁的是该 Class 对象(全局唯一)
注意:两个线程即使操作不同实例,但如果 synchronized 锁的是同一个对象(比如共享的 lockObj),依然会互斥。
wait 和 sleep 的关键区别
这是高频对比点:
-
wait()是 Object 方法,释放锁;sleep()是 Thread 的静态方法,不释放任何锁 -
wait()必须在 synchronized 中调用;sleep()可以在任意地方调用 -
wait()可被 notify 唤醒;sleep()到时自动恢复,或被 interrupt 中断
为什么推荐用 while 而不是 if 检查条件再 wait
防止虚假唤醒(spurious wakeup)和条件竞争:
- 线程被 notify 后重新获得锁,但此时共享状态可能已改变(如其他线程抢先修改了条件)
- 用
while (condition) wait();可确保每次醒来都重新判断条件是否真正满足 - 经典范式:synchronized(obj) { while (!ready) obj.wait(); }
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










