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
приведет к исключению.