javamultithreadingillegalmonitorstateexcep

IllegalMonitorStateException Java


I'm doing some work for the university in which we have to develop a monitor in Java that gives us mutual exclusion and synchronization of resources. The brain of this monitor is a system modeled with Petri net which gives us the synchronization between processes. This monitor must have a queue for blocked processes (which could not access the monitor) and a queue for the conditional variable (if this process is not synchronized). When threads are blocked (by a traffic light) they are saved in a vector and then by a FIFO policy to awaken. The problem occurs when a thread is about to exit the monitor you want to wake a sleeping thread in one IllegalMonitorStateException vector is produced (in the Signal () method of the class SemaforoFIFO right in the notify ()) and do not know why. I was reading a lot about wait () and notify () but can not find solution. I'm sure the problem is that I do not know both the subject and I think, but hopefully can make me understand this problem and serve me in the future. Thank you.

Forgive me for my English. I'm from Argentina and use the Google translator. Bye

Here is the code below:

Class Vehiculo: Initializes the thread that handles shoot different transitions in the Petri net (interact with the resource). These feature an array with all transitions.

Class Monitor: is responsible for providing mutual exclusion and synchronization processes.

Class procesadorPetri: is responsible for taking the transition number you want to shoot the vehicle and verify whether the conditions exist for this shot. If the conditions are not met the thread should sleep. Otherwise the shot is taken and the system status is updated.

Class varCondicional: is responsible for providing the synchronization of processes.

Class semaforoFIFO: is responsible for providing mutual exclusion within the monitor.

This is the error I get when I run the program:

Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at Modelo.SemaforoFifo.Signal(SemaforoFifo.java:40)
at Modelo.VarCondicionales.RESUME(VarCondicionales.java:51)
at Modelo.Monitor.disparo(Monitor.java:51)
at Modelo.Vehiculos.run(Vehiculos.java:35)

Class Monitor:

public class Monitor {

private Semaforo mutex;
private VarCondicionales cond;
private procesadorPetri p;
private Vector<Object> colaEspera;

public Monitor(procesadorPetri p){

    colaEspera = new Vector<Object>();
    mutex = new SemaforoFifo(1, colaEspera);
    cond = new VarCondicionales(mutex);
    this.p = p;

}

public void disparo(int t) {

    mutex.Wait();

    while( !p.verificar(t) )
    {
        cond.DELAY();
    }

    p.Disparo(t);

    System.out.println("El hilo " + Thread.currentThread().getName() + " disparó " + p.getElNombreTransicion(t));

    p.mostrarEstado();

    System.out.println("La cola del monitor tiene " + colaEspera.size() + " hilos bloqueados");
    System.out.println("La cola de la variable de condicion tiene " + cond.Size() + " hilos bloqueados");

    cond.RESUME();

    System.out.println();
}

}

Class varCondicionales:

import java.util.Vector;


public class VarCondicionales {

private Semaforo mutex;

private Semaforo condicion;

private Vector<Object> colaBloqueados;

public VarCondicionales(Semaforo sem) {

    mutex = sem;

    colaBloqueados = new Vector<Object>();

    condicion = new SemaforoFifo(0, colaBloqueados);

}

public void DELAY() {

    mutex.Signal();
    condicion.Wait();
    mutex.Wait();
}

public void RESUME() {

    if(colaBloqueados.size() > 0) {

        condicion.Signal();

    }
    else

        mutex.Signal();

    }

public int Size(){

    return colaBloqueados.size();

}

}

Class semaforoFIFO:

import java.util.Vector;

public class SemaforoFifo implements Semaforo {

private int val;

private Vector<Object> colaBloqueados;

public SemaforoFifo(int t, Vector<Object> cola){

    val = t;

    colaBloqueados = cola;

}

public synchronized void Wait() {

    while(val == 0){

        try {

            colaBloqueados.add(Thread.currentThread());
            wait();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    val=0;
}

public synchronized void Signal() {

    if(colaBloqueados.size() > 0){

        colaBloqueados.firstElement().notify(); //despierto al primer hilo de la cola y
        colaBloqueados.removeElementAt(0); //      lo elimino de la cola

    }

    val=1;

}

}

Class Vehiculo:

package Modelo;


public class Vehiculos extends Thread{

Monitor monitor;

private int[] disparos;

public Vehiculos (Monitor m, int[] a){

    monitor = m;
    disparos = a;
}

public void run(){

    while(true){

        try{

            for(int i=0; i<disparos.length ; i++){
                monitor.disparo(disparos[i]);
                sleep(100);
            }

        } catch(InterruptedException e){
            e.printStackTrace();

        }
    }
}

public void getDisparos(){

    for(int i=0; i<disparos.length;i++){
        System.out.print(disparos[i] + " ");
    }

}
}

Class procesadorPetri:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

public class procesadorPetri {

private int[] m_estado;
private int[][] m_incidencia;
private String[] nombreTransiciones;
private String[] nombrePlazas;
private int n_transiciones;
private int n_plazas;

public procesadorPetri (String PatchIncidencia, String PatchEstado, String PatchNombres){

    n_transiciones = 0;
    n_plazas = 0;

    getCaracteristicas(PatchIncidencia, PatchEstado);

    m_incidencia = new int[n_plazas][n_transiciones];
    m_estado = new int[n_plazas];

    nombreTransiciones = new String[n_transiciones];
    nombrePlazas = new String[n_plazas];

    getMatrices(PatchIncidencia, PatchEstado, PatchNombres);

}

private void getMatrices(String patchIncidencia, String patchEstado, String patchNombres) {

    try {

        String[] aux;
        String linea;

        BufferedReader br1 = new BufferedReader(new FileReader(patchIncidencia));

        for(int j=0, i=0; (linea = br1.readLine()) != null; i++ , j=0){

            aux = linea.split(" ");

            while(j<n_transiciones){

                m_incidencia[i][j] = Integer.parseInt(aux[j]);

                j++;
            }

        }
        br1.close();

        BufferedReader br2 = new BufferedReader(new FileReader(patchEstado));

        linea = br2.readLine();

        aux = linea.split(" ");

        int i = 0;

        while(i<n_plazas){

            m_estado[i] = Integer.parseInt(aux[i]);
            i++;
        }

        br2.close();

        BufferedReader br3 = new BufferedReader(new FileReader(patchNombres));

        linea = br3.readLine();

        aux = linea.split(" ");

        for(i=0 ; i<n_transiciones;i++){
            nombreTransiciones[i] = aux[i];
        }


        linea = br3.readLine();

        aux = linea.split(" ");

        for(i=0 ; i<n_plazas;i++){
            nombrePlazas[i] = aux[i];
        }

        br3.close();

    }catch (Exception e){

        System.out.println("Error al leer los archivos..");
        e.printStackTrace();
    }

    mostrarIncidencia();
    System.out.println();
    mostrarEstado();
    System.out.println();
    System.out.println();
    System.out.println("se termino de leer la matriz de incidencia..");

    System.out.println("se termino de leer la matriz de estado..");

    System.out.println("\n");

}

private void getCaracteristicas(String patchIncidencia, String patchEstado) {

    String l;
    String[] aux;
    int bandera = 0;

    try {

        BufferedReader br1 = new BufferedReader(new FileReader(patchIncidencia));

        while((l = br1.readLine()) != null){

            n_plazas++;

            if(l != null && bandera == 0){

                aux = l.split(" ");
                n_transiciones = aux.length;
                bandera=1;

            }
        }

        System.out.println("El sistema consta de: PLAZAS = " + n_plazas + " TRANSICIONES = " + n_transiciones);

        br1.close();

    } catch (IOException e) {
        e.printStackTrace();
    }

}

public void mostrarIncidencia(){

    System.out.println();

    for(int i = 0; i<n_plazas ; i++){

        for(int j = 0; j < n_transiciones ; j++){

            System.out.printf( "%2d ", m_incidencia[i][j]);

        }
        System.out.println();
    }

}

public void mostrarEstado(){

    System.out.print( "[");
    for(int i = 0 ; i < n_plazas ; i++ ){

        System.out.printf( "%2d ", m_estado[i]);

    }
    System.out.println( "]");
}

public int getNumeroPlazas(){
    return n_plazas;
}

public int getNumeroTransiciones(){
    return n_transiciones;
}

public void Disparo(int t){

    for(int i=0; i<n_plazas;i++){

        m_estado[i] = m_estado[i] +  m_incidencia[i][t];
    }

    //System.out.println("Se disparo la transicion " + getElNombreTransicion(t));
}

public String getElNombreTransicion(int t){

    return nombreTransiciones[t];

}

public String getElNombrePlaza(int t){

    return nombrePlazas[t];
}

public ArrayList<Integer> disparosDisponibles(){

    ArrayList<Integer> lista = new ArrayList<Integer>();

    boolean verificacion = true;
    //System.out.print("Disparos disponibles: ");
    for(int i=0; i<n_transiciones;i++){

        for(int j =0; j< n_plazas && verificacion != false; j++ ){

            if((m_estado[j] + m_incidencia[j][i]) < 0){
                verificacion = false;
            }
        }

        if(verificacion){
            //System.out.print(getElNombreTransicion(i) + " ");
            lista.add(i);

        }else{
            verificacion = true;
        }
    }
    //System.out.println();
    return lista;

}

public boolean verificar(int t){

    ArrayList<Integer> disparosPosibles = disparosDisponibles();

    if(disparosPosibles.size() == 0){

        return false;
    }

    for(Integer i : disparosPosibles){

        if(i.intValue() == t){
            //System.out.println("true");
            return true;
        }

    }
    //System.out.println("false");
    return false;

}

}

Class Main:

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;


public class Main {

public static void main(String[] args){

    String PatchVehiculos =   "C:\\Users\\Gringo\\Documents\\Workspace Java\\FINAL\\src\\Datos\\Vehiculos.txt";
    String PatchNombres =     "C:\\Users\\Gringo\\Documents\\Workspace Java\\FINAL\\src\\Datos\\Nombres.txt";
    String PatchInicidencia = "C:\\Users\\Gringo\\Documents\\Workspace Java\\FINAL\\src\\Datos\\Incidencia.txt";
    String PatchEstado =      "C:\\Users\\Gringo\\Documents\\Workspace Java\\FINAL\\src\\Datos\\Estado.txt";

    String linea;
    String[] aux;
    ArrayList<int[]> lista= new ArrayList<int[]>();
    ArrayList<Vehiculos> hilos= new ArrayList<Vehiculos>();
    procesadorPetri p = new procesadorPetri(PatchInicidencia,PatchEstado,PatchNombres);

    Monitor m = new Monitor(p);

    try {

        BufferedReader br1 = new BufferedReader(new FileReader(PatchVehiculos));

        for(int i=0 ; (linea = br1.readLine()) != null ; i++){

            aux = linea.split(" ");

            lista.add(new int[aux.length]);

            for(int j = 0; j < aux.length ; j++){

                for(int k = 0 ; k < p.getNumeroTransiciones() ; k++){

                    if(aux[j].equals(p.getElNombreTransicion(k))){

                        lista.get(i)[j] = k;

                    }
                }
            }

            hilos.add(new Vehiculos(m, lista.get(i)));

        }

        br1.close();

        for(int i=0; i<hilos.size(); i++){

            hilos.get(i).start();

        }

    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

}

Solution

  • In your Signal method, you call notify on the first element in your Vector. The problem is that due to the method being synchronized, the thread owns the monitor of the current class instance, and not the element in the Vector.

    The Signal method is effectively the same as...

    public void Signal() {
        synchronized (this) {
            // ...
        }
    }
    

    ...so attempting to call notify, notifyAll, or wait on an object that is not the current instance of SemaforoFifo will result in the exception being thrown.