关于Java中的生产者消费者模型的问题

huangapple go评论78阅读模式
英文:

A question about Producer-Consumer Model in Java

问题

我编写了一个Java程序来解决多线程中的生产者消费者问题,但它无法正常工作。
以下是程序的代码和错误信息:

public class ConsumerAndProducer {
    static int products = 0;
    static int capacity = 10;

    public static void main(String[] args) {
        new Thread(new Producer()).start();
        new Thread(new Consumer()).start();
    }

    static class Consumer implements Runnable {
        public void consume() {
            synchronized (ConsumerAndProducer.class) {
                if (products <= 0) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                products--;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Consumer, remain:" + products);
                if (products == 9) {
                    notify();
                }
            }
        }

        @Override
        public void run() {
            while (true) {
                consume();
            }
        }
    }

    static class Producer implements Runnable {
        public void produce() {
            synchronized (ConsumerAndProducer.class) {
                if (products == capacity) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                products++;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Producer, remain:" + products);
                if (products == 1) {
                    notify();
                }
            }
        }

        @Override
        public void run() {
            while (true) {
                produce();
            }
        }
    }
}

错误信息:

Producer, remain:1
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at zhousai.ConsumerAndProducer$Producer.produce(ConsumerAndProducer.java:69)
at zhousai.ConsumerAndProducer$Producer.run(ConsumerAndProducer.java:77)
at java.lang.Thread.run(Thread.java:748)
Consumer, remain:0
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at zhousai.ConsumerAndProducer$Consumer.consume(ConsumerAndProducer.java:22)
at zhousai.ConsumerAndProducer$Consumer.run(ConsumerAndProducer.java:43)
at java.lang.Thread.run(Thread.java:748)

希望这可以帮助你解决问题。

英文:

I write a Java program to solve Producer Consumer problem in Multi-Threads. But it can not work correctly.
The program:

public class ConsumerAndProducer {
static int  products = 0;
static int capacity = 10;
public static void main(String[] args) {
new Thread(new Producer()).start();
new Thread(new Consumer()).start();
}
static class Consumer implements Runnable{
public void consume() {
synchronized (ConsumerAndProducer.class){
if(products &lt;= 0){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
products--;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(&quot;Consumer, remain:&quot; + products);
if(products == 9){
notify();
}
}
}
@Override
public void run() {
while(true){
consume();
}
}
}
static class Producer implements Runnable{
public void produce() {
synchronized (ConsumerAndProducer.class){
if(products == capacity){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
products++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(&quot;Producer, remain:&quot; + products);
if(products == 1){
notify();
}
}
}
@Override
public void run() {
while(true){
produce();
}
}
}

And the errors:

Producer, remain:1
Exception in thread &quot;Thread-0&quot; java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at zhousai.ConsumerAndProducer$Producer.produce(ConsumerAndProducer.java:69)
at zhousai.ConsumerAndProducer$Producer.run(ConsumerAndProducer.java:77)
at java.lang.Thread.run(Thread.java:748)
Consumer, remain:0
Exception in thread &quot;Thread-1&quot; java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at zhousai.ConsumerAndProducer$Consumer.consume(ConsumerAndProducer.java:22)
at zhousai.ConsumerAndProducer$Consumer.run(ConsumerAndProducer.java:43)
at java.lang.Thread.run(Thread.java:748)

答案1

得分: 1

当我运行您的代码时,我得到了以下错误:

线程Thread-0中的异常java.lang.IllegalMonitorStateException当前线程不是所有者

引发该异常的代码行是对方法wait()的调用。
您正在调用Producer类的wait()方法,但您正在ConsumerAndProducer.class上进行同步。必须在拥有锁的对象上调用wait()方法,因为该对象拥有锁,您必须在拥有锁的对象上调用wait()。因此出现错误消息:current thread not owner

最简单的解决方案是更改您的代码,使您调用ConsumerAndProducer.class.wait(),而不仅仅是wait()

以下是已经应用了我的建议修复的代码:

public class ConsumerAndProducer {
    static int products = 0;
    static int capacity = 10;
    public static void main(String[] args) {
        new Thread(new Producer()).start();
        new Thread(new Consumer()).start();
    }

    static class Consumer implements Runnable {
        public void consume() {
            synchronized (ConsumerAndProducer.class){
                if (products <= 0) {
                    try {
                        ConsumerAndProducer.class.wait(); // 在此处更改
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                products--;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Consumer, remain:" + products);
                if(products == 9){
                    ConsumerAndProducer.class.notify(); // 在此处更改
                }
            }
        }

        @Override
        public void run() {
            while(true){
                consume();
            }
        }
    }

    static class Producer implements Runnable{
        public void produce() {
            synchronized (ConsumerAndProducer.class){
                if (products == capacity) {
                    try {
                        ConsumerAndProducer.class.wait(); // 在此处更改
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                products++;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Producer, remain:" + products);
                if(products == 1){
                    ConsumerAndProducer.class.notify(); // 在此处更改
                }
            }
        }

        @Override
        public void run() {
            while(true){
                produce();
            }
        }
    }
}
英文:

When I ran your code, I got the following error:

Exception in thread &quot;Thread-0&quot; java.lang.IllegalMonitorStateException: current thread is not owner

The line of your code throwing that exception is the call to method wait().
You are calling method wait() of class Producer but you are synchronizing on ConsumerAndProducer.class. The wait() method must be called on the object that you are synchronizing on, because that object owns the lock and you must call wait() on the object that owns the lock. Hence the error message: current thread not owner.

The simplest solution is to change your code such that you call ConsumerAndProducer.class.wait() rather than just wait().

Here is your code with my suggested fix:

public class ConsumerAndProducer {
    static int  products = 0;
    static int capacity = 10;
    public static void main(String[] args) {
        new Thread(new Producer()).start();
        new Thread(new Consumer()).start();
    }

    static class Consumer implements Runnable {
        public void consume() {
            synchronized (ConsumerAndProducer.class){
                if (products &lt;= 0) {
                    try {
                        ConsumerAndProducer.class.wait(); // change here
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                products--;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(&quot;Consumer, remain&quot; + products);
                if(products == 9){
                    ConsumerAndProducer.class.notify(); // change here
                }
            }
        }

        @Override
        public void run() {
            while(true){
                consume();
            }
        }
    }

    static class Producer implements Runnable{
        public void produce() {
            synchronized (ConsumerAndProducer.class){
                if (products == capacity) {
                    try {
                        ConsumerAndProducer.class.wait(); // change here
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                products++;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(&quot;Producer, remain&quot; + products);
                if(products == 1){
                    ConsumerAndProducer.class.notify(); // change here
                }
            }
        }

        @Override
        public void run() {
            while(true){
                produce();
            }
        }
    }
}

huangapple
  • 本文由 发表于 2020年7月24日 10:55:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/63066056.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定