import java.util.LinkedList;
import java.util.Queue;
class Producer extends PubSub implements Runnable{
@Override
public void run() {
synchronized(queue){
if (queue.size() == 99){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
queue.add(2);
try{
Thread.sleep(1000);
}
catch (InterruptedException e){
e.printStackTrace();
}
notify();
}
}
}
class Consumer extends PubSub implements Runnable{
@Override
public void run() {
synchronized(queue){
if(queue.isEmpty()){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(queue.poll());
}
}
}
public class PubSub {
static Integer QUEUE_SIZE = 100;
Queue<Integer> queue = new LinkedList<Integer>();
public static void main(String[] args) {
Producer producer = new Producer();
Consumer consumer = new Consumer();
Thread producerThread = new Thread(producer);
Thread consumerThread = new Thread(consumer);
producerThread.start();
consumerThread.start();
System.out.println("Started both the threads");
}
}
I am getting a java.lang.IllegalMonitorStateException
in the wait()
part. I want to know what I am doing wrong here. Any ideas??
The complete exception that I get is as follows.
Exception in thread "Thread-1" Started both the threads
java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at Consumer.run(PubSub.java:36)
at java.lang.Thread.run(Thread.java:745)
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at Producer.run(PubSub.java:23)
at java.lang.Thread.run(Thread.java:745)
I think that I got your code working ...
As stated by JB Nizet you have to invoke wait and notify on the queue
object.
I think that such object must be declared static
to be shared by Producer and Consumer.
I have included while loops for the code to continue running until the end of time.
Also, an extra notify
is needed before Producer and Consumer first wait
Here is your code with that changes included:
import java.util.LinkedList;
import java.util.Queue;
class Producer extends PubSub implements Runnable{
@Override
public void run() {
int index = 0;
while (true) {
synchronized(queue){
while (queue.size() == QUEUE_SIZE){
try {
System.out.println("Producer waits");
queue.notify();
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Produce element " + (++index));
queue.add(2);
queue.notify();
try {
Thread.sleep(1000);
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
}
class Consumer extends PubSub implements Runnable{
@Override
public void run() {
while (true) {
synchronized(queue) {
while (queue.isEmpty()){
try {
System.out.println("Consumer waits");
queue.notify();
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consume element " + queue.poll());
queue.notify();
}
}
}
}
public class PubSub {
static Integer QUEUE_SIZE = 100;
static Queue<Integer> queue = new LinkedList<Integer>();
public static void main(String[] args) {
Producer producer = new Producer();
Consumer consumer = new Consumer();
Thread producerThread = new Thread(producer);
Thread consumerThread = new Thread(consumer);
producerThread.start();
consumerThread.start();
System.out.println("Started both the threads");
}
}