如果wait(timeout)和notifyAll()被同一个对象锁定,则timeout的含义是什么

时间:2015-04-28 11:31:27

标签: java multithreading concurrency

对于以下代码,notifyAll()将保持锁定直到完成,即使超时已达到,此块也不会保持锁定并且必须等待notifyAll()块完成。 那么等待(超时)超时的含义是否在超时完成后我们还要等待锁定?另外 - 如何更改代码以使超时具有意义?

// one thread
synchronized (lock) {
  lock.wait(timeout);
}

// second thread
synchronized (lock) {
  // do some processing actions.......
  lock.notifyAll();
}

3 个答案:

答案 0 :(得分:3)

您确实是正确的,等待线程实际上经历了两种类型的等待:等待显式的' notify / notifyAll',然后等待机会获得同步锁。

希望是,大多数其他线程使用' synchronized'只会在短时间内保持同步锁定。这是一个非常强烈推荐的做法。 它的一个私人案例是调用' notifyAll' - 这是一个非常短的动作,同步块很快就存在了。

总结一下:线程可能会卡在' lock.wait'很长一段时间(例如"等待客户到达" - 这可能需要几个小时,你可能会考虑超时,之后你会对业务感到绝望)。但是,一旦通知到达并且它在同步'上竞争。 - 这场比赛应该简短,如此简短,以至于考虑超时是不值得的。然而,这依赖于你的程序员的良好意愿,它应该只对短块使用synchronized(例如,当你更新变量时,在一小段时间内避免竞争条件)。这是一个良好的实践问题。

答案 1 :(得分:0)

等待超时具有良好的意义。只需阅读和JavaDoc并考虑一下。不知道为什么你认为它没有任何意义,我想你只是感到困惑。

  

导致当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法,或者已经过了指定的时间量。

     

当前线程必须拥有此对象的监视器。

Object.wait(long)

答案 2 :(得分:0)

有些情况,lock.wait()等待资源,可能永远不可用(永远不会调用lock.notify())。例如,如果远程计算机崩溃(或网络崩溃),则永远不会收到来自远程计算机的响应。

在这种情况下,一种选择是永远等待,允许用户中断等待。

另一个选择是使用lock.wait(timeout)等待有限的时间,假设资源在该金额到期后无法访问。在这种情况下(超时过期后)程序可以选择另一种方式来完成任务。或者程序可以简单地退出并允许其他程序完成他们的工作。

不考虑虚假的唤醒,使用很简单:

if(!condition)
{
    lock.wait(timeout);
    if(!condition)
    {
        //timeout expired while waiting
    }
}
// 'condition' is true now