为什么wait()在消费者无法从生产者notifyall()获得通知?

时间:2015-01-03 15:46:27

标签: java

以下是我的代码

public class Factory {

    static boolean iteminfactory = false;
    public synchronized void producer(int i ) throws InterruptedException {
        System.out.println("Producer started " + iteminfactory);
        if (iteminfactory) {
            wait();
        }

        System.out.println("Produced " + i);
        iteminfactory = true;
        notifyAll();
        System.out.println("Producer ended " + iteminfactory);
    }

public synchronized void consumer() throws InterruptedException {
    System.out.println("Consume started " + iteminfactory);
        if (!iteminfactory) {
            wait();   //  problem , not able to get notification from producer
        }

        System.out.println("Consumed");
        iteminfactory = false;
        notifyAll();
        System.out.println("Consumer ended " + iteminfactory);
    }

}

// producer
package com.example.suri;

public class Producer implements Runnable{
    static Factory f;

    public Producer () {
        f = new Factory();
    }
    @Override
    public void run() {
        for (int i = 0; i < 10 ; ++i) {
        try {
            f.producer(i);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        }
    }
}

//consumer

public class Consumer implements Runnable {
static Factory f;

    public Consumer() {
        f = new Factory();
    }
    @Override
    public void run() {

        for (int i = 0; i < 10 ; ++i) {
            try {
                f.consumer();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

// main

public static void main(String[] args) {

        Producer p = new Producer();
        Consumer c = new Consumer();

        Thread tp = new Thread(p);
        Thread tc = new Thread(c);

        tp.start();
        tc.start();
    }

output

Producer started false
Consume started false
Produced 0
Producer ended true
Producer started true

等待内部消费者功能没有收到生产者的通知。为什么会这样? 如果我为Factory创建单个实例并与消费者和生产者共享,那么一切正常。即改变这样的构造函数。

Producer(Factory fact) {
f = fact;
}
Consumer (Factory fact) {
f = fact;
}

// Main
Factory f = new Factory();
Producer p = new Producer(f);
Consumer c = new Consumer(f);

但我的问题是为什么notifyall()区分工厂实例,因为它应该只通知正在等待的线程

1 个答案:

答案 0 :(得分:2)

wait / notify / notifyAll api尝试在封闭实例上获取互斥锁。因此,如果您正在等待来自object1的通知,那么只有object1可以通知而不是object2。

有关详细信息,请参阅this

The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution. 

在Factory中,您正在同步此对象,即在特定实例上。在生产者和消费者类中,您正在实例化工厂,因此您有两个不同的实例,因此您在两个不同的实例上进行同步。

我建议你通过构造函数注入工厂,这样生产者和消费者都可以使用相同的工厂实例,因此可以在公共工厂对象上进行同步。