通知呼叫后,线程未获取监视器

时间:2014-10-07 07:27:49

标签: java multithreading

我刚刚创建了一个生产者和一个消费者线程。当列表为空时,消费者进入等待状态,然后生产者在列表中插入一个项目并调用notify()来调用消费者线程但消费者没有调用。它仍处于等待状态。

我尝试的代码是:

package xs;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class TestMain {
    public static void main(String[] args) {
        product pro = new product();
        producer produce = new producer(pro);
        consumer consume = new consumer(pro);
        Thread thr1 = new Thread(produce, "Producer");
        Thread thr2 = new Thread(consume, "consumer");
        thr1.start();
        thr2.start();
    }
}

class product{
    List<Date> list;
    public product() {
        list = new ArrayList<Date>();
    }

    public void produce(Date i){
        list.add(i);
    }

    public Date consume(){
        return list.remove(0);
    }
}

class producer implements Runnable{
    product product;
    @Override
    public void run() {
        while(true){
            synchronized (this) {
                while(product.list.size() == 2){
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                product.produce(new Date());
                System.out.println("Produced "+product.list.size());
                notify();
            }
        }
    }


    public producer(product product) {
        this.product = product;
    }

}

class consumer implements Runnable{
    product product;
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            synchronized (this) {
                notify();
                while(product.list.size() == 0){
                    try {
                        System.out.println("Going to wait..."+ product.list.size());
                        wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println("consumed"+ product.consume());
            }
        }
    }

    public consumer(product product) {
        this.product = product;
    }
}

输出它给出:

Going to wait...0
Produced 1
Produced 2

正如您所见,消费者在wait()致电后没有采取行动。

2 个答案:

答案 0 :(得分:2)

您的制作人和消费者都在同步,等待和通知他们自己的监视器。您需要为它们提供共享监视器以用于同步等。

例如:

Object monitor = new Object();
product pro = new product();
producer produce = new producer(monitor, pro);
consumer consume = new consumer(monitor, pro);

更改producerconsumer构造函数以接受另一个参数(类型为Object)并将其保存在字段中,然后将synchronized(this)更改为synchronized(monitor) },wait()monitor.wait()notify()monitor.notify(),一切都会好的。

(你可以只使用product进行同步,但我个人更喜欢使用用于同步的对象,或者一个专门为此设计的以线程为中心的类。)

另外,请注意,由于您的类名称应该ProductProducerConsumer来遵循正常的Java命名约定,因此您的代码感觉非常类似于Java。 / p>

答案 1 :(得分:-2)

@deepak:你犯了一个错误,你通过了字符串名称小写
线程thr2 =新线程(消费,“消费者”);

到位你应该通过  线程thr2 =新线程(消耗,“消费者”);

其中“消费者”是消费者的类名

我得到了这个输出:

Produced 1
Produced 2
consumedTue Oct 07 13:29:44 IST 2014
consumedTue Oct 07 13:29:44 IST 2014
Going to wait...0