IllegalMonitorStateException Java

Я делаю некоторую работу для университета, в котором мы должны разработать монитор на Java, который дает нам взаимное исключение и синхронизацию ресурсов. Мозг этого монитора - это система, смоделированная с помощью сети Петри, которая дает нам синхронизацию между процессами. Этот монитор должен иметь очередь для заблокированных процессов (которые не могли получить доступ к монитору) и очередь для условной переменной (если этот процесс не синхронизирован). Когда потоки заблокированы (светофором), они сохраняются в векторе, а затем в соответствии с политикой FIFO для пробуждения. Проблема возникает, когда поток собирается выйти из монитора, вы хотите разбудить спящий поток в одном векторе IllegalMonitorStateException (в методе Signal () класса SemaforoFIFO прямо в notify ()) и не знаете, почему. Я много читал о wait () и notify (), но не могу найти решение. Я уверен, что проблема в том, что я не знаю и предмет, и думаю, но, надеюсь, может заставить меня понять эту проблему и послужить мне в будущем. Спасибо.

Прости меня за мой английский. Я из Аргентины и использую переводчик Google. до свидания

Вот код ниже:

Класс GTulo: Инициализирует поток, который обрабатывает различные переходы в сети Петри (взаимодействует с ресурсом). Они имеют массив со всеми переходами.

Class Monitor: отвечает за обеспечение взаимного исключения и синхронизации процессов.

Класс ProcessadorPetri: отвечает за получение номера перехода, который вы хотите снимать с автомобиля, и проверяет, существуют ли условия для этого выстрела. Если условия не выполняются, поток должен спать. В противном случае снимок сделан, и статус системы обновляется.

Класс varCondicional: отвечает за обеспечение синхронизации процессов.

Класс semaforoFIFO: отвечает за обеспечение взаимного исключения внутри монитора.

Это ошибка, которую я получаю при запуске программы:

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)

Монитор класса:

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();
}

}

Класс 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();

}

}

Класс семафоро FIFO:

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;

}

}

Класс ГИБДУло:

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] + " ");
    }

}
}

Класс процессадора Петри:

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;

}

}

Главный класс:

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();
    }

}

}

1 ответ

Решение

В вашем Signal метод, который вы называете notify на первый элемент в вашем векторе. Проблема заключается в том, что из-за синхронизируемого метода потоку принадлежит монитор текущего экземпляра класса, а не элемент в векторе.

Signal метод фактически такой же, как...

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

... так пытаюсь позвонить notify, notifyAll, или же wait на объекте, который не является текущим экземпляром SemaforoFifo приведет к исключению.

Другие вопросы по тегам