在SYNCHRONIZATION中使用内部锁

时间:2013-07-30 18:15:56

标签: java multithreading synchronization

假设d是我们用来调用wait的对象。当一个线程调用d.wait时,它必须拥有d的内部锁 - 否则抛出错误。在同步方法中调用wait是获取内部锁的一种简单方法。

这是否意味着两个线程不能同时调用wait()?内在锁在这里意味着什么[提到它作为监视器]?但是如何实现监控以实现互斥?

一旦线程调用wait它会永远保存对象吗? 如果是这样,使用该锁的其他线程如何用于notifyAll()?

如果我们需要在notifyall期间获取对象,那么为什么所有等待的线程都会被通知? 不应该只通知等待该对象的线程吗?

任何要解释的代码都表示赞赏。

4 个答案:

答案 0 :(得分:3)

  

所以这意味着两个线程不能同时调用wait()   时间?

纠正两个线程不能同时调用wait()。但是,一旦一个线程进入wait(),另一个线程就可以获得相同的锁并在不久之后进入wait()状态。你可以在同一个对象上有任意数量的线程WAITING,但只有一个确实持有锁。

  

这里的内在锁是什么意思[提到它作为监视器]?但   如何实现监控以实现互斥?

持有对象时只能运行一个线程。其他线程可能阻塞尝试获取锁定,更多可以等待()。

  

一旦线程调用wait它会永远保存对象吗?

相反,它放弃它或其他线程几乎可以立即获得它。

  

如果是这样的话   关于使用该锁的其他线程的notifyAll()?

如果在对象上调用notifyAll(),则依次唤醒所有wait()转换线程。这些线程一次只能获取一个锁,并且会尽快重新获取锁。

  

如果我们需要在notifyall期间获取对象,那么为什么所有人都在等待   线程通知?

这就是notifyAll所做的,它被认为比使用notify更安全,后者唤醒随机的一个,因为它不太容易出现编码错误。

  

不应该只通知等待该对象的线程吗?

这就是它的作用。


你应该注意到;

  • 在通知()/ notifyAll()之前,您应该执行状态更改。你还应该在一个循环中wait()来检查状态的变化。你需要这样做,因为a)wait()可能会错过一个notify(),b)它可以虚假地唤醒c)另一个线程可能会抓住你所做的任何事情,它可能需要再次等待。
  • 在过去的9年中,更多地使用了高级并发类。使用这些类意味着您不需要直接使用线程,队列,wait()和notify()。

答案 1 :(得分:1)

  

在synchronized方法中调用wait是一种简单的获取方法   本能锁定。

Wait不提供对象的锁定,而是让线程在其他线程调用notify时等待侦听锁定释放。线程在进入受保护的// synchronized块时获取锁定。同步块/方法允许锁定(如果可用),否则线程无法进入这些代码块。

答案 2 :(得分:0)

根据javadoc:

,锁不会永远存在
  

线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。然后该线程等待,直到它可以重新获得监视器的所有权并继续执行。

答案 3 :(得分:0)

当您致电wait()时,您释放该对象的内在锁定,直到另一个线程在其上调用notify()notifyAll()。此时,JVM将唤醒其中一个线程等待,并自动重新获取该对象的锁定。

所以回答你的问题,是的,多个线程可以wait()在同一个对象上。