2010-07-06 46 views
8

我知道调用Object的wait()方法会释放对象监视器(如果存在)。java:wait(),notify()和同步块

但是我有一个关于另一个线程此对象上调用notify()一些问题:

  1. (时)将等待线程唤醒,如果另一个(第3)线程拥有的同时,对象监视器?

  2. 将等待线程唤醒,如果第3个线程在此对象上调用wait()

  3. 是可以确定如果一个线程等待通知特定对象(Java的1.4/Java 5中)

  4. 发生了什么事,如果wait()将在finalize()方法叫什么名字?

回答

2
  1. notify会唤醒显示器上等待的一个线程。除非并且直到显示器未被占用,否则不能等待线程运行;必须在同步块中调用wait(),因此必须保持该锁继续运行该块。
  2. 无保证。致电notifyAll给所有线程机会唤醒。
  3. Dunno。你可以让线程设置一个变量,说它在进入睡眠之前正在等待...
  4. 这可能是一个坏主意。你能想出这种情况吗?
+0

1.“必须在同步块中调用wait()”是错误的。但它应该。 2.是的,你是对的。 3.我认为Chris Denett就在这里。 Thread.holdsLock()听起来不错。 4.这是理解这些概念的理论问题。 – MRalwasser 2010-07-14 19:36:50

+1

@MRalwasser:不同意,它必须。看看这里:http://stackoverflow.com/questions/2779484/why-must-wait-always-be-in-synchronized-block/ – Marcus 2014-01-30 17:28:37

2
  1. 这就是为什么你有notify()notifyAll()方法。前者唤醒一个等待对象的线程,后者唤醒所有线程。如果在另一个线程中调用wait(),则等待的线程不会唤醒。

  2. 这是唯一可以调用thread.holdsLock(obj)看到如果一个线程拥有特定对象上保持监视器锁号。

  3. 请勿以最终方法调用wait()

+0

我接受2 - 4。但是你对1的回答是错误的。我在说锁监视器(同步块) – MRalwasser 2010-07-14 19:38:39

0

2:不一定。 notify()醒来一个的等待线程。它可能是原始的或第三个。

3:使用thread.getState()你可以发现一个线程是否在等待一个对象,但是我不知道你是否总能准确地找出它是哪个对象。

3

当您从线程调用wait()时,该线程将停止执行,并将其添加到该对象的等待集中。当您从另一个线程调用notify()时,如果调用notifyAll(),则会从waitset中唤醒一个随机线程,所有将准备执行。

当你调用notify(),线程准备运行,但它并不意味着它会被执行inmediately所以要小心。

  1. 它会随机唤醒一个等待集中的线程。

  2. 你不知道哪一个会首先被唤醒,它不会按照任何顺序。

  3. Thread.getState()

  4. 你会产生死锁。