调用wait()时,等待的是引用指向的对象还是引用本身?附代码场景问询
关于Java中wait()/notify()的两个核心问题解答
嘿,这两个问题其实戳中了Java并发里一个很容易混淆的点——到底wait/notify是跟引用走还是跟对象走,我来给你掰扯清楚:
问题1:当对引用调用wait()方法时,该方法是等待引用指向的对象,还是等待引用本身?
答案很明确:等待的是引用指向的对象,而非引用变量本身。
wait()、notify()、notifyAll()这些方法都是定义在Object类里的,它们操作的是对象内部的「等待集」(wait set)——这是每个对象自带的一个线程集合,用来存放等待该对象通知的线程。引用只是一个指向对象的"别名",当你通过调用reference.wait()时,JVM会直接找到这个引用当前指向的对象,然后把当前线程加入到该对象的等待集里。引用本身只是个存储地址的变量,没有自己的等待集,也没法被"等待"。
问题2:给定代码场景,线程1是否会被实际唤醒?
先把你的代码整理成更清晰的格式:
static Object lock = new Object(); // 线程1的代码 Object reference = lock; reference.wait(); // 线程2的代码 lock.notify();
结论是:线程1会被成功唤醒。
原因很简单:reference和lock这两个引用指向的是同一个Object实例。线程1调用reference.wait()时,是把自己加入到了这个共享对象的等待集;线程2调用lock.notify()时,是从同一个对象的等待集里唤醒一个线程——刚好就是线程1。
👉 额外提个关键注意点:实际写代码时,调用wait()和notify()必须先持有该对象的锁(也就是要把代码放在synchronized(reference)或者synchronized(lock)这样的同步块里),否则会直接抛出IllegalMonitorStateException,你的示例代码里省略了同步块,但核心逻辑是成立的。
内容的提问来源于stack exchange,提问作者Waseem
相关产品推荐
相关产品推荐

