【发布时间】:2014-10-27 07:04:12
【问题描述】:
在下面的生产者和消费者问题中,如何在不使用同步方法的情况下,在下面的程序中将线程从一个对象通知到另一个对象。
我为put 和get 方法使用queue 类,并在Producer 类和Consumer 类的run() 方法中使用wait() 和notify()。
我的目标是在Producer 类和Consumer 类中使用wait() 和notify() 方法,而不是在Queue 类中使用它们。
它给出了一个IllegalMonitorStateException。
程序:
package threads;
class Queue{
int num;
int get(int number)
{
System.out.println("The Consumer "+number+" got "+num);
return num;
}
void put(int n,int number)
{
this.num=n;
System.out.println("The producer "+number+" put "+this.num);
}
}
public class producerandconsumer{
boolean flag=false;
class Producer implements Runnable{
Queue q;
int number;
Producer(Queue q,int number)
{
this.q=q;
this.number = number;
new Thread(this,"Producer").start();
}
public void run()
{
for(int i=0;i<10;i++)
{
while(flag)
try{
wait();
}
catch(InterruptedException e){
System.out.println("InterruptedException caught ");
}
q.put(i,number);
flag=true;
notify();
}
}
}
class Consumer implements Runnable{
Queue q;
int number;
Consumer(Queue q,int number)
{
this.q=q;
this.number=number;
new Thread(this,"Consumer").start();
}
public void run()
{
for(int i=0;i<10;i++)
{
while(!flag)
try{
wait();
}
catch(InterruptedException e){
System.out.println("InterruptedException caught ");
}
flag=false;
notify();
q.get(number);
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
producerandconsumer pc= new producerandconsumer();
Queue q=new Queue();
pc.new Producer(q,1);
pc.new Consumer(q,1);
}
}
程序的输出:它给出了一个IllegalMonitorStateException。
The producer 1 put 0 Exception in thread "Producer"
java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at threads.producerandconsumer$Producer.run(producerandconsumer.java:48)
at java.lang.Thread.run(Unknown Source)
Exception in thread "Consumer" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at threads.producerandconsumer$Consumer.run(producerandconsumer.java:76)
at java.lang.Thread.run(Unknown Source)
【问题讨论】:
-
使用阻塞队列。使用 BlockingQueue 时不需要使用等待和通知。队列将等待并通知线程。消费者只需从队列中获取项目,队列会阻塞它,直到有可用的项目。生产者只是将项目放入队列中,并被队列阻塞,直到队列中剩余空间(如果它是有界的)。
-
线程之间共享的对象是Queue,所以你必须在那里同步,而不是在Producer/Consumer!
-
将使用阻塞队列..谢谢@JB Nizer 和 isnot2bad。
标签: java multithreading wait producer-consumer notify