我正在尝试用Java实现Producer使用者问题。我正在尝试实现一种功能,其中Producer将项目推送到堆栈并等待消费者使用它。消费者在尝试使用它之前等待堆栈有一些值。
这应该在无限循环中发生。问题是代码只运行一次然后我得到以下异常:
Exception in thread "Thread-0" Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at com.nik.threads.Producer.run(Producer.java:28)
java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at com.nik.threads.Consumer.run(Consumer.java:28)
问题出在notify()
电话上。我知道问题正在发生,因为线程并不知道要通知谁,因为它不知道等待的线程。但我无法实现它。以下是我的代码:
Producer.java:
class Producer extends Thread{
private Stack<Integer> stack;
public Producer(Stack<Integer> stack){
this.stack=stack;
}
@Override
public void run() {
for(int i=0;;i++){
if(!stack.isEmpty())
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
stack.push(i);
try {
sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
notify();
} }
}
Consumer.java:
class Consumer extends Thread{
private Stack<Integer> stack;
public Consumer(Stack<Integer> stack){
this.stack=stack;
}
@Override
public void run() {
for(;;){
if(stack.isEmpty())
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Consumed:"+stack.pop());
try {
sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ProducerConsumer.java:
import java.util.Stack;
public class ProducerConsumer {
public static void main(String[] args) throws InterruptedException {
Stack<Integer> stack=new Stack<>();
Producer p=new Producer(stack);
Consumer c=new Consumer(stack);
p.start();
c.start();
}
}
答案 0 :(得分:0)
您需要在您呼叫等待的监视器上进行同步并在
上进行通知synchronized(this) wait();
和
synchronized(this) notify();
(在你的情况下)
(还有一些其他问题,比如,总是检查循环中的等待条件并使用专用的监视器对象,而不是等待并通知,并使用notifyAll而不是notify)