1
class SimpleConsumer extends Threads {
        public SyncQueue q;
        SimpleConsumer(SyncQueue q) { this.q = q; }
        public void run () { doit(); }
        public synchronized void doit() {
            while(true){
                try{
                    while(q.isEmpty()) { wait(); }
                    System.out.println((String)q.Dequeue());
                } 
                catch (Exception e) { System.out.println("Got exception:" +e); }
            }
        }    
    }

そして、同じオブジェクト SyncQueue にアイテムを追加し、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); }
        }
    }
}
} 

別のクラス メソッドから notifyAll() を実行すると、SimpleConsumer は起動しますか?

4

1 に答える 1

3

2 つの異なるオブジェクトを待機して通知しているため、互いに通信しません。wait共通オブジェクトを使用し、その共通オブジェクトで メソッドとメソッドを呼び出す必要がありnotifyAllます。

例えば:

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); }
        }
    }    
}

ノート:

  • q参照が外部から変更されないように、非公開かつ最終的なものにしました。
  • 同期ブロックのモニターは、 ではなくキュー自体になりthisました。
于 2013-02-05T14:11:57.500 に答える