2013-02-12 79 views
3

我正在阅读关于Condition对象以及它们如何为每个对象提供多个等待集并区分哪个对象或对象/线程组获得特定信号。
为什么不经常Object这样做?例如。条件与对象等待/通知

相反的:

final Condition notFull = lock.newCondition(); 
final Condition notEmpty = lock.newCondition();  

lock.lock(); 
try { 
    while (count == items.length) 
    notFull.await(); 
    items[putptr] = x; 
    if (++putptr == items.length) putptr = 0; 
     ++count; 
    notEmpty.signal(); 

我们这样做:

final Object notFull = new Object();  
final Object notEmpty = new Object();  

lock.lock(); 
try { 
    while (count == items.length) 
    notFull.wait(); 
    items[putptr] = x; 
    if (++putptr == items.length) putptr = 0; 
     ++count; 
    notEmpty.notify(); 

难道我们还有多观望台,并通知线程间的区别?

回答

1

当您拨打waitnotify时,您首先需要synchronize。当您需要两套不同的套件时,需要两个对象进行同步。嵌套同步会导致死锁。

+0

但条件我仍然需要'条件'对象 – Jim 2013-02-12 12:36:45

+1

只要你必须锁定一个锁对象,而不是两个不同的锁,两个条件是可以的。这是你无法用显示器做的。 – 2013-02-12 12:47:33

+0

这里有很多关于这个话题的问答。请参阅http://stackoverflow.com/questions/3190545/java-wait-notify-and-synchronized-blocks和http://stackoverflow.com/questions/2779484/why-wait-should-always-be-in-synchronized - 块,为eaxmple。 – 2013-02-12 13:35:32

0

这不好。您必须拥有该对象的监视器才能使用其notFull.wait()方法。即使它被允许,它仍然不会释放lock,所以没有其他线程可以访问它。

3

在你的例子中,你在一个锁上创建了2个条件。这是你无法使用内置同步的方法 - 你必须使用2个对象来获得2个条件。

而你的第二个代码被破坏,因为你没有锁定notFull和notEmpty,但是调用wait/notify - 你会得到IllegalMonitorStateException。但是如果你试图锁定它们,你会发现你不能同时做到这一点。这是区别

+0

所以它只是“保存”没有对象? – Jim 2013-02-12 12:46:34

+0

不,它避免了由于必须在嵌套同步块中获取两个不同监视器而导致的死锁。 – 2013-02-12 12:48:35

+0

@RalfH:嵌套同步死锁。有没有可能举一个这样的例子? – Jim 2013-02-12 12:59:20