2012-01-25 64 views
5

我只是有一个问题关于同时运行的线程和锁对象。据我所知,调用wait()方法的线程将进入等待列表,并允许阻塞列表中的另一个线程接管锁和对象(在同步代码中)。 如果此线程现在具有对象的锁定,则会调用notify()方法,唤醒调用wait()的线程并将其移至阻止列表。了解多线程

调用notify()方法的线程会发生什么情况。它是否仍然锁定对象,或者现在是否在等待列表中?

关于

回答

5

只有一个线程可以容纳一个对象的锁。当线程持有你调用这些方法的对象的锁时,必须调用wait()notify()方法;如果他们不(例如,因为你没有在对象上同步),你会得到一个IllegalMonitorStateException

当您调用wait()时,线程放弃锁定并等待列表(停止执行)。当wait()返回时,线程将再次获得锁定。但是,调用notify()的线程仍然保持锁定状态,因此等待的线程在通知线程退出​​块或方法之前不会恢复,以便它释放对象的锁定。

通过调用notify()线程不放弃锁定对象。

事件的可能的顺序是:

  • 线程1进入一个​​块,从而获得锁定的对象
  • 线程在对象上1个通话wait(),放弃锁,停止执行
  • 线程2进入一个​​块,获得锁的对象的对象
  • 线程2调用notify(),但仍持有锁
  • 线程1被唤醒并尝试获得锁,但它不能因为线程2仍然有它(这样线程1必须等待锁)
  • 线程2退出​​块和释放锁
  • 线程1现在可以获得锁并从wait()返回
4

通知线程仍然拥有锁定。请参见doc第17.14节(页面底部):

只有当当前线程已锁定对象的锁定时,才应该为对象调用notify方法。如果等待设置的对象不是空的,则某些任意选择的线程将从等待集中移除并重新启用以进行线程调度。 (当然,直到当前线程放弃对象的锁定,该线程才能继续)。

1

不,它将通过保留同步块或从同步方法返回来释放锁。在再次拨打wait()之前,它不会返回到等待列表。