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

c9qzyr3d  于 2021-07-13  发布在  Java
关注(0)|答案(3)|浏览(377)

对于以下代码,notifyall()将保持锁定直到完成,即使达到超时,此块也不会保持锁定,必须等待notifyall()块完成。那么等待中的超时(timeout)是什么意思呢?如果超时完成后,我们仍然要等待锁?另外-如何更改代码以便超时有意义?

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

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

xpszyzbs1#

您确实正确,等待线程实际上经历了两种类型的等待:等待显式的'notify/notifyall',然后等待获得同步锁的机会。
希望是,大多数其他使用“synchronized”的线程只会在短时间内保持同步锁。这是一个非常强烈的建议做法。它的一个私有示例是调用'notifyall'的线程——这是一个非常短的操作,并且同步块很快就存在了。
总而言之:线程可能会在“lock.wait”上停留很长一段时间(例如“等待客户到达”-这可能需要几个小时,您可能会考虑一个超时时间,之后您会对业务感到绝望)。然而,一旦通知到达并且它在“synchronized”上竞争,这个竞争应该是简短的,如此简短以至于不值得考虑超时。然而,这依赖于你的程序员同伴的善意,他们应该只在短的块中使用synchronized(例如,当你更新一个变量时,在那一瞬间避免一个竞争条件)。这是一个好的做法。

szqfcxe2

szqfcxe22#

等待的超时有很好的意义。读一读javadoc,好好想想。我不知道你为什么认为它在这里没有意义,我猜你只是困惑了。
使当前线程等待,直到另一个线程为此对象调用notify()方法或notifyall()方法,或者经过指定的时间。
当前线程必须拥有此对象的监视器。
对象。等待(长)

uttx8gqw

uttx8gqw3#

有些情况下 lock.wait() 等待可能永远不可用的资源( lock.notify() 从未被调用)。例如,如果远程计算机崩溃(或网络崩溃),将永远不会接收到它的响应。
在这种情况下,一种选择是永远等待,允许用户手动中断等待。
另一种选择是使用 lock.wait(timeout) 等待一段有限的时间,假定资源在该时间到期后不可访问。在这种情况下(超时过期后),程序可以选择另一种方式来完成任务。或者程序可以简单地退出并允许其他程序执行它们的工作。
在不考虑虚假唤醒的情况下,用法很简单:

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

相关问题