Java 线程在notify调用后未获取监视器

Java 线程在notify调用后未获取监视器,java,multithreading,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

我刚刚制作了一个制作人和一个消费者线程。当列表为空时,消费者进入等待状态,然后生产者在列表中插入一项并调用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;
    }
}

正如你们所看到的,消费者在等待电话后并没有采取行动

您的生产者和消费者都在同步、等待并通知他们自己的监视器。您需要为他们提供一个共享监视器,用于同步等

例如:

Object monitor = new Object();
product pro = new product();
producer produce = new producer(monitor, pro);
consumer consume = new consumer(monitor, pro);
将生产者和消费者构造函数都更改为接受Object类型的另一个参数并将其保存在字段中,然后将synchronizedthis更改为synchronizedmonitor,wait更改为monitor.wait,notify更改为monitor.notify,一切都会好起来

您可以使用产品在上进行同步,但我个人更喜欢使用仅用于同步的对象,或者使用专门为此设计的以线程为中心的类的对象


另外,请注意,由于您的类名应该是Product、Producer和Consumer,以遵循正常的Java命名约定,因此您的代码感觉非常不象Java。

@deepak:您犯了一个错误,将字符串名称小写 Thread thr2=新线程消费,消费者

在你应该通过的地方 Thread thr2=新线程消费,消费者

其中Consumer是Consumer的类名

我得到了这个输出:

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

你是说IPC只存在于同一个监视器中?@DeepakTiwari:这里没有IPC-你只有一个进程!但是,每个监视器在同步、等待和通知方面是独立的。如果整个系统在逻辑上只有一个监视器,那么编写可伸缩代码就很难了。谢谢你的帮助:我采用了你的方法,但是由于这个原因,我得到了非法的MonitorStateException。你可以看到编辑过的问题。它已更改为您建议的名称。它只是线程名称。它与类名无关。
Produced 1
Produced 2
consumedTue Oct 07 13:29:44 IST 2014
consumedTue Oct 07 13:29:44 IST 2014
Going to wait...0