Java Wait()和NotifyAll()

Java Wait()和NotifyAll(),java,multithreading,Java,Multithreading,我还有另一个类,它将项添加到同一个对象SyncQueue,并执行notifyAll() 如果我从另一个类方法执行notifyAll(),SimpleConsumer会醒来吗?您正在等待并通知两个不同的对象,因此它们不会相互交谈。您需要使用一个公共对象,并在该公共对象上调用wait和notifyAll方法 例如: class SimpleProducer extends Threads { public SyncQueue q; SimpleProducer(SyncQueue q) { this

我还有另一个类,它将项添加到同一个对象SyncQueue,并执行notifyAll()


如果我从另一个类方法执行notifyAll(),SimpleConsumer会醒来吗?

您正在等待并通知两个不同的对象,因此它们不会相互交谈。您需要使用一个公共对象,并在该公共对象上调用
wait
notifyAll
方法

例如:

class SimpleProducer extends Threads {
public SyncQueue q;
SimpleProducer(SyncQueue q) { this.q = q; }
public void run() { doit(); }
public synchronized void doit() {
    while(true){
        try{
            sleep(1000);
            q.Enqueue("Item");
            notifyAll();
            } catch(Exception e) { System.out.println("Got exception:" +e); }
        }
    }
}
} 
注:

  • 我已将
    q
    private和final设置为private和final,以确保引用未被外部更改
  • 同步块的监视器现在位于队列本身,而不是

您尝试时发生了什么?SimpleConsumer没有醒来……您必须等待同一个对象,通知所有正在调用的对象。顺便说一句,无论您试图做什么,使用ExecutorService都会更简单。@OP请注意,这要求同步块也将该对象用作监视器(因此:
synchronized(monitor){
,而不是声明方法
synchronized
。因此,我无法执行q.wait()在consumer中,如果我不执行synchronized(q)块?@TheNotMe当你调用
someObject.wait()
,你需要在
synchronized(someObject)
块中,否则你会在运行时得到一个
IllegalMonitorException
。你应该检查这个选项,它解释了所有这些。
class SimpleProducer extends Threads {
public SyncQueue q;
SimpleProducer(SyncQueue q) { this.q = q; }
public void run() { doit(); }
public synchronized void doit() {
    while(true){
        try{
            sleep(1000);
            q.Enqueue("Item");
            notifyAll();
            } catch(Exception e) { System.out.println("Got exception:" +e); }
        }
    }
}
} 
class SimpleConsumer extends Threads {
    private final SyncQueue q;

    SimpleConsumer(SyncQueue q) {
        this.q = q;
    }

    public void doit() {
        while(true){
            try{
                synchronized(q) {
                    while(q.isEmpty()) { q.wait(); }
                    System.out.println((String)q.Dequeue());
                }
            } 
            catch (Exception e) { System.out.println("Got exception:" +e); }
        }
    }    
}