|
|
1
4
如果对象在调用object.wait()时不拥有对象监视器,则在释放监视器之前,它将无法访问该对象以设置通知侦听器。相反,它将被视为试图访问同步对象上的方法的线程。 或者换一种说法,两者没有区别:
以及以下方法:
两种方法都将被阻止,直到对象监视器被释放。这是Java中的一个特性,用于防止对象被多个线程更新的状态。它只会对wait()方法产生意外的结果。 假设wait()方法没有同步,因为这可能会导致线程在对象上拥有多个锁的情况。(参见 Java Language Specifications/Locking 有关这方面的详细信息。)多个锁是一个问题,因为wait()方法将只撤消一个锁。如果方法是同步的,它将保证只有方法的锁会被撤销,同时仍然会保留一个潜在的外部锁。这将在代码中创建死锁条件。 为了回答您在thread.sleep()上的问题,thread.sleep()不能保证满足您等待的任何条件。使用object.wait()和object.notify()可以让程序员手动实现阻塞。一旦发送满足条件的通知,线程将取消阻止。例如,从磁盘读取已完成,线程可以处理数据。thread.sleep()要求程序员轮询是否满足条件,如果不满足条件则返回睡眠状态。 |
|
2
14
这里已经有很多好的答案了。但是这里要提到的是,另一个在使用wait()时必须做的是在一个依赖于您所等待的条件的循环中完成它,以防您看到虚假的唤醒,这在我的经验中确实发生过。 要等待其他线程将条件更改为true并通知:
当然,现在,我建议您只使用新的Condition对象,因为它更清晰并且具有更多的特性(例如,允许每个锁有多个条件,能够检查等待队列长度,更灵活的调度/中断等)。
} |
|
|
3
5
它需要拥有监视器,因为wait()的目的是释放监视器,并让其他线程获得监视器来进行自己的处理。这些方法(wait/notify)的目的是协调两个线程之间对同步代码块的访问,这些线程需要彼此执行某些功能。不仅要确保对数据结构的访问是线程安全的,还要协调多个线程之间的事件。 一个典型的例子是生产者/消费者案例,其中一个线程将数据推送到队列,另一个线程使用数据。消耗线程将始终要求监视器访问队列,但在队列为空时将释放监视器。当使用者不再处理时,生产者线程将只获得对该线程的写访问权。一旦将更多的数据推送到队列中,它就会通知使用者线程,这样它就可以重新获得监视器并再次访问队列。 |
|
|
4
5
等等,放弃显示器,所以你必须让它放弃。通知也必须有监视器。 之所以要这样做,主要是为了确保从wait()返回时拥有监视器——通常,您使用wait/notify协议来保护某些共享资源,并且希望在wait返回时能够安全地触摸它。与notify相同——通常您正在更改一些内容,然后调用notify()——您希望拥有监视器、进行更改,并调用notify()。 如果你做了这样的功能:
当wait返回时,您将没有监视器——您可以得到它,但下一步可能不会得到它。 |
|
|
5
3
下面是我对为什么限制实际上是一个需求的理解。我把它基于一个C++监视器实现,我通过组合互斥体和条件变量做了一段时间。 在一个 mutex+条件变量=监视器 系统 wait 调用将条件变量设置为等待状态并释放互斥体。条件变量是共享状态,因此需要锁定它,以避免希望等待的线程和希望通知的线程之间的争用条件。而不是引入另一个互斥锁来锁定其状态,而是使用现有的互斥锁。在Java中,当等待线程拥有监视器时,互斥锁被正确地锁定。 |
|
|
6
3
如果有一个条件,比如队列是空的,那么通常会等待。
假设队列是空的。 如果当前线程在检查队列之后先发制人,那么如果另一个线程 线程向队列添加了一些元素,当前线程将不知道,并将等待 状态。错了。 所以我们应该有
现在让我们考虑一下,如果它们使wait本身保持同步会怎么样。正如其中一条注释中所提到的,它只释放一个锁。这意味着如果在上面的代码中同步wait(),那么只会释放一个锁。意味着当前线程将等待队列的锁。 |
|
|
user29759326 · 如何返回递归函数中的最后一个值? 1 年前 |
|
|
malife89 · 将java中的字符串读取为正确的日期格式 1 年前 |
|
|
Tim · 在java中,有没有更快的方法将字节数组写入文件? 1 年前 |
|
|
rudraraj · java中未声明最终变量 1 年前 |
|
|
Bala Ji · 以下BFS的实施效率如何? 1 年前 |