2009-05-06 30 views

回答

6

这是完全正常的。您只能通知在一台显示器上等待的所有内容。其他人都不感兴趣。您调用notifyAll的对象只是其他人正在等待的显示器。如果没有人在等待没有人需要通知

8

正如您在这里看到的,在不等待的对象上调用notifyAll()没有任何影响。

alt text

+0

它可能不是完全正确把一个线程等待对notifyAll的运行,或者至少在没有需要提醒的是一个通知线程做的第一件事就是regrab监视器锁定。而且由于通知的线程数量中只有一个可以获取,所以其他人将被阻止。但阻塞与等待不同,因为阻塞的线程不需要另一个notify()信号。 – 2012-01-20 15:52:52

1

只有等待对象得到通知。 Object.wait()阻塞,直到超时或通知 - 所以问题仍然是如何或为什么你会认为非等待的对象会得到通知?这个不成立。

+0

对象不会等待或被通知 - 线程可以。在监视器对象上调用notifyAll()而不知道是否有线程在等待它是完全可能的和正常的。例如,在具有队列的生产者/消费者场景中,当生产者向队列中添加新元素并通知所有正在等待(即无)消费者时,消费者可能已经清空了队列并仍然被处理占用。 – 2009-05-06 08:45:01

+0

我消除了线程以尽可能简化事情。 – 2009-05-06 10:54:03

2

对象“等待”,不等待自己。线程正在等待。如果没有人在等待,没有人会醒来,没有什么特别的事情会发生。

+0

当闹铃响起但没人听到时会发生什么? – 2012-01-20 15:43:34

2

完全正常的情况。

假设你有一个生产者线程的队列将元素放入其中,并且一个消费者线程从中删除元素。

现在消费者可能已经清空了队列,仍然处于占用状态,因此没有人正在等待队列变为非空。现在生产者在队列中添加一个新元素。如果它正在等待,他必须调用notifyAll()来唤醒消费者。添加额外的逻辑来检查是否有人正在等待,只有在这种情况下调用notifyAll()才会增加场景的复杂度(并且非常容易出错) - 每次只调用notifyAll()会更容易。

1

我可能只会分裂毛发;-)认为在notifyAll上从'等待'状态变为'运行'状态的线程可能不是严格正确的;至少不是没有告诫告知线程所做的第一件事就是重新监视监视器锁定。而且由于通知线程数量中只有一个可以获取它,其他人将被阻止BLOCKEDThread.State.Blocked)是线程状态。但阻塞是不等于,因为阻塞的线程不需要另一个notify()信号来恢复。 [那么我知道虚假的唤醒,但是对于一些JVM实现来说也许是相反的 - 错过了通知?]

public class HellBoy { 
    public static class MyThread extends Thread { 
     static final public Object sharedLock = new Object(); 

     public void run() { 
      synchronized (sharedLock) { 
       System.out.println("Gonna wait..."); 
       try { 
        sharedLock.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       System.out.println("Woken up but sleeping with the lock"); 
       try { 
        Thread.sleep(2500); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       System.out.println("exiting and unlocking"); 
      } 
     } 
    } 

    public static void main(String[] args) throws Exception { 
     new MyThread().start(); 
     new MyThread().start(); 
     new MyThread().start(); 
     new MyThread().start(); 
     Thread.sleep(200); 
     synchronized (MyThread.sharedLock) { 
      MyThread.sharedLock.notifyAll(); 
     } 
    } 
} 
相关问题