Los métodos ingresar y retirar de Cuenta deben estar sincronizados, y la clase Persona en run(), ya que debe descender de Thread, tendrá que hacer un ingreso, una retirada y alternarlos con algún sleep.
Mi problema surge a la hora de hacer la llamada desde Persona a Cuenta para ingresar dinero. Aparece el siguiente error:
Exception in thread "Thread-1" Exception in thread "Thread-4" Exception in thread "Thread-2" Exception in thread "Thread-3" java.lang.NullPointerException
at ej3.Persona.run(Persona.java:19)
java.lang.NullPointerException
at ej3.Persona.run(Persona.java:19)
java.lang.NullPointerException
at ej3.Persona.run(Persona.java:19)
java.lang.NullPointerException
at ej3.Persona.run(Persona.java:19)
No entiendo porque me sale. ¿Me podéis ayudar a comprender el fallo?
El código de todas las clases es el siguiente:
Clase Cuenta
Código Java:
Ver original
package ej3; public class Cuenta { // Propiedades private int numClientes = 0; private boolean validarOperacion = false; // Valido la operacion y eliminar al cliente en clase Banco private int turnoCliente = 1; private int saldoActual; private int saldoMaximo; // ¿Por qué un saldo máximo? Me haría ilusión que no me limiten el dinero que pueda tener... private int estadoCuenta = -1; private Persona ultimoCliente; // Constructor public Cuenta(int saldoActual, int saldoMaximo){ this.saldoActual = saldoActual; this.saldoMaximo = saldoMaximo; } // Métodos public void setNumClientes(int x){ this.numClientes = x; } public int getEstadoCuenta(){ return estadoCuenta; } public synchronized void ingresar(int cantidad, int turno, Persona ultimoCliente){ /* Codigos de resultado: * -1 = No es su turno * -2 = saldoMaximo excedido * otra cantidad = ingreso correcto */ while (validarOperacion == false || turnoCliente != turno){ try{ wait(); } } // Fin de while if (turno == turnoCliente){ if (saldoActual + cantidad <= saldoMaximo){ saldoActual = saldoActual + cantidad; estadoCuenta = cantidad; } else{ estadoCuenta= -2; } this.ultimoCliente = ultimoCliente; validarOperacion = false; // Disponible para validar clientes if (turnoCliente == numClientes) turnoCliente = 1; else turnoCliente++; } // Fin de if notifyAll(); } // Fin ingresar public synchronized void retirar(int cantidad, int turno, Persona ultimoCliente){ while (validarOperacion == false || turnoCliente != turno){ try{ wait(); } } // Fin de while if (turno == turnoCliente){ if (saldoActual - cantidad >= 0){ saldoActual = saldoActual - cantidad; estadoCuenta = cantidad; } else{ estadoCuenta = -2; } this.ultimoCliente = ultimoCliente; validarOperacion = false; // Disponible para validar clientes if (turnoCliente == numClientes) turnoCliente = 1; else turnoCliente++; } // Fin de if notifyAll(); } // Fin retirar // Si el usuario ha hecho una operacion incorrecta, este método lo expulsa desde Clase Banco @SuppressWarnings("deprecation") public synchronized void validarUsuario(){ while (validarOperacion == true){ try{ wait(); } } // Fin de while if (this.estadoCuenta == -2){ ultimoCliente.stop(); } validarOperacion = true; notifyAll(); } }
Clase Persona
Código Java:
Ver original
package ej3; // Propiedades private int numCliente; private Cuenta cuenta; // Constructor this.nombre = nombre; this.numCliente = numCliente; } // Métodos public void run(){ while(true){ cuenta.ingresar(generarCifra(), numCliente, this); try{ sleep(300); } cuenta.retirar(generarCifra(), numCliente, this); try{ sleep(300); } } // Fin while } // Fin run public int generarCifra(){ } return nombre; } }
Clase Banco (la uso para alternar las clases persona y matar los hilos si se exceden al retirar o ingresar dinero
Código Java:
Ver original
package ej3; // Propiedades private Cuenta cuenta; // Constructor public Banco(Cuenta cuenta){ this.cuenta = cuenta; } // Métodos public void run(){ while (true){ cuenta.validarUsuario(); } } // Fin de run }
Main
Código Java:
Ver original
package ej3; import java.util.Vector; public class Main { Cuenta cuenta = new Cuenta(2000, 10000); Vector<Persona> gente = new Vector<Persona>(); Banco banco = new Banco(cuenta); gente.addElement(new Persona("Inazio", 1)); gente.addElement(new Persona("Paula", 2)); gente.addElement(new Persona("Ana", 3)); gente.addElement(new Persona("Edu", 4)); cuenta.setNumClientes(gente.size()); banco.start(); for (int i = 0; i < gente.size(); i++){ gente.elementAt(i).start(); } } }