【问题标题】:Where does the thread execution begin when it is notified by another thread?当另一个线程通知它时,线程执行从哪里开始?
【发布时间】:2014-05-21 17:22:14
【问题描述】:
public  void add(int num)
{
 synchronized(myObject){
 // line 1
 //line 2
 while(!condition)
 {
  myObject.wait();
  //line 3
 }    
 //line 4
 //line 5
 //line 6
 }
}

当一个线程 T(等待 myObject 上的锁)被通知时,
T 从哪里开始执行,在第 1 行或第 3 行?谢谢。

【问题讨论】:

  • 当你尝试时会发生什么?

标签: java multithreading wait synchronized notify


【解决方案1】:

在第 3 行,线程执行是线性的,它
不能回去,也不能跳到那样的地方。

【讨论】:

  • 但是如果myObject正被另一个线程使用,那么这个线程怎么可能进入block呢?
  • 顺便说一句,这个代码示例应该是myObject.wait()。否则,除非myObject == this 或除非代码也在由this 同步的块中,否则在尝试调用this.wait() 时会出现异常。
  • @peter.petrov...感谢您的回复。我已根据您的更正编辑了问题。
【解决方案2】:

被通知的线程需要重新获取锁,但是重新获取发生在等待调用中,并且线程一旦从等待方法返回就拥有锁,然后它在第 3 行开始执行。Peter's answer是正确的 (+1)。

javadoc for wait 支持这一点,它说:

线程 T 然后从该对象的等待集中移除并重新启用线程调度。然后它以通常的方式与其他线程竞争对象同步的权利;一旦它获得了对象的控制权,它对对象的所有同步声明都将恢复到之前的状态——即,恢复到调用等待方法时的状态。线程 T 然后从调用等待方法返回。因此,从等待方法返回时,对象和线程 T 的同步状态与调用等待方法时完全相同。

你可以测试一下。如果线程必须在块的顶部重新开始,那么您可以通过 if 测试来检查条件,因为一旦通知线程,它仍然必须通过条件测试。如果线程从中断的地方继续,则需要 while 循环,因为线程需要检查使其必须等待的条件是否仍然为真。如果您用 if 语句替换 while 循环并运行多线程测试(例如,您可以创建一个队列,这是一个可以篡改其 put 和 take 方法的本地队列,在消费者所在的位置有多个生产者和消费者等待队列非空)然后您应该能够看到线程等待的情况,然后即使条件不允许它继续(导致尝试从空队列中获取某些内容)。

【讨论】:

  • @Nathan...感谢您的回复。这也消除了我的主要(或父母)对为什么只应在循环中调用 wait 的疑问。到目前为止,我一直假设执行从第 1 行开始。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-12
  • 1970-01-01
  • 2018-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多