/ / IllegalMonitorStateException al compartir el objeto - multihilo

IllegalMonitorStateException al compartir el objeto - multihilo

Estoy tratando de crear productor de una sola variablesolución para el consumidor, pero estoy obteniendo IllegalMonitorStateException en el método notifyAll () del productor. También estoy adquiriendo el bloqueo en el bloque sincronizado, ¿qué podría haber salido mal?

/**
* Write a description of class SingleProducerConsumer here.
*
* @author (your name)
* @version (a version number or a date)
*/
public class SingleProdCons
{

public static void main(String args[])
{
Integer x = 0;
Thread producer = new Thread(new Producer(x),"Producer");
Thread consumer = new Thread(new Consumer(x),"Consumer");
producer.start();
consumer.start();
}
}

class Producer implements Runnable
{
private Integer x;

Producer(Integer x)
{
this.x = x;
}

@Override
public void run()
{
synchronized(x)
{
while(x.equals(0)==false){

//The value of the variable has not been consumed yet , we should wait here till it gets consumed
try{
x.wait();
}catch(InterruptedException ie)
{
System.out.println("Caught Exception : "+ie.getMessage());
}

}

//Else initialze the variable and let it get used by the Consumer then
synchronized(x)
{
x=10;
x.notifyAll();

}
}

}

}

class Consumer implements Runnable
{
private Integer x;

Consumer(Integer x)
{
this.x = x;
}

@Override
public void run()
{
synchronized(x)
{
while(x.equals(0)==true)
{
//The value has not been put by the Producer thread yet hence we should wait here
System.out.println("We are before the method call of the wait on the x object");
try{
x.wait();
}catch(InterruptedException ie)
{
System.out.println("Caught the exception : "+ie.getMessage());
}
}
}

synchronized(x)
{
System.out.println("Consuming : "+x);
x.notifyAll();
}

}

}

Exception in thread "Producer" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at Producer.run(SingleProdCons.java:55)
at java.lang.Thread.run(Thread.java:745)
Exception in thread "Producer" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at Producer.run(SingleProdCons.java:55)
at java.lang.Thread.run(Thread.java:745)
Exception in thread "Producer" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at Producer.run(SingleProdCons.java:55)
at java.lang.Thread.run(Thread.java:745)
Exception in thread "Producer" java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at Producer.run(SingleProdCons.java:55)
at java.lang.Thread.run(Thread.java:745)

Respuestas

2 para la respuesta № 1

Este es el problema:

synchronized(x)
{
x=10;
x.notifyAll();
}

Es importante entender que no se sincroniza en una variable - te sincronizas en un objeto. Por lo que se modifica el valor de x para referirse a un diferente Integer objeto, y entonces estás llamando notifyAll en ese objeto diferente ... de un hilo que no posee el monitor para ese objeto.

Te aconsejo fuertemente que no uses Integer Objetos para sincronizar en absoluto. Lo ideal es usar un objeto que no se use para alguna otro propósito - que hace que sea más fácil razonar.

Todavía puedes tener tu x variable, y documente que no debe modificarse de manera diferente a cuando el hilo mantiene el bloqueo apropiado, pero que sea independiente del bloqueo en sí.