1
El lenguaje de programación JAVA
Conceptos avanzados:Tratamiento de Excepciones
Programación basada en Hilos
Tratamiento de Excepciones
Tratamiento básico
2
A.Ortigosa POO - EPS - UAM 3
Excepciones
Forma de evitar salir mal del programacuando se produce un error: Volver a estado seguro y seguir ejecutando Permitir guardar el trabajo y salir de forma
“agradable” Cuando se detecta un error, se lanza (throw)
un objeto (excepción) Encapsula información del error
A.Ortigosa POO - EPS - UAM 4
Excepciones: Código
try { ... obj.f (); ...}
catch (DivisionCero obj) { ...}
void f () throws DivisionCero { ... if (...) throw new DivisionCero (x, y); ...}
3
A.Ortigosa POO - EPS - UAM 5
Tratamiento de Excepciones
Permiten saltar de un punto a otro del programaindependientemente de su localización
Salto acompañado de información Utilidad: tratamiento de errores (error recovery)
Throw envía información en forma de un objeto de unaclase determinada
Este objeto contiene información sobre un error ocurrido Cada catch recoge una clase de objetos, el resto los
ignora
A.Ortigosa POO - EPS - UAM 6
Manipulador de Excepciones
La ejecución se transfiere al manipulador quepueda “lidiar” con la situación
ManipuladorExcepciones
Manipulador Excepciones
4
A.Ortigosa POO - EPS - UAM 7
¿Quién se hace cargo?
Cuando un método lanza una excepción, el RTS busca quiénlo trate:
main
Método conmanejador deexcepciones
Método sinmanejador deexcepciones
Método dondeocurre el error
invocación
invocación
invocación
lanzaexcepción
lanzaexcepción
atrapaexcepción
A.Ortigosa POO - EPS - UAM 8
Requisito: Atrapar o Declarar
Un método debe o bien capturar o biendeclarar todas las excepciones comprobadasque pueden ser lanzadas por ese método. Clases de excepciones. Lanzamiento de excepciones. Capturar excepciones. Declarar (relanzar) excepciones.
5
A.Ortigosa POO - EPS - UAM 9
Clasificación de Excepciones
Todas las excepciones son instancias declases derivadas de Throwable
Throwable
Error Exception
IOException RuntimeException
A.Ortigosa POO - EPS - UAM 10
Tipos de Excepciones
Error (y subclases) Errores internos y agotamiento de recursos. No deben lanzarse excepciones de este tipo. Poco se puede hacer al respecto
RuntimeException Error de programación (debería haber sido
evitado). Excepción derivada de Error o RuntimeError no comprobada
Otras excepciones comprobadas
6
A.Ortigosa POO - EPS - UAM 11
Requisito: Atrapar o Declarar
Un método debe o bien atrapar o biendeclarar todas las excepciones comprobadasque pueden ser lanzadas por ese método. Clases de excepciones. Lanzamiento de excepciones. Capturar excepciones. Declarar (relanzar) excepciones.
A.Ortigosa POO - EPS - UAM 12
Lanzamiento de Excepciones
Cuándo un método lanza una excepción: Se invoca un método que lanza excepción. Se detecta un error y se lanza (explícitamente)
una excepción. Se provoca un error de programación. Se produce error interno en la máquina virtual en
en la biblioteca de ejecución.
7
A.Ortigosa POO - EPS - UAM 13
Lanzamiento de Excepciones
throw new IOException();throw new IOException(“El fichero” + filename + “ no existe”);
Procedimiento: Localizar la clase de excepción apropiada. Construir un objeto de esa clase. Lanzarlo.
Una vez que un método dispara unaexcepción, no hay que preocuparse por elvalor de retorno.
A.Ortigosa POO - EPS - UAM 14
Ejemplo de lanzamiento deexcepciones
void retirar(int cantidad) throws SaldoInsuficiente, CuentaBloqueada { if (bloqueada) throw new CuentaBloqueada (numero); else if (cantidad > saldo) throw new SaldoInsuficiente (numero, saldo); else saldo -= cantidad; }
8
A.Ortigosa POO - EPS - UAM 15
Ejemplo de lanzamiento deexcepciones
public class ListOfNumbers { private Vector victor; private static final int SIZE = 10;
... public void writeList() {
PrintWriter out = new PrintWriter( new FileWriter("OutFile.txt"));
for (int i = 0; i > SIZE; i++) { out.println("Value at: " + i + " = " +
victor.elementAt(i)); } out.close();
} }
comprobado
Runtime error
A.Ortigosa POO - EPS - UAM 16
Lanzamiento de Excepciones
No siempre deben declararse las excepcionesque se lanzan: Sólo se deben declarar las excepciones
comprobadas que se puedan lanzar. Otra alternativa es atraparlas. Las de tipo Error están fuera de control. Las RuntimeException no deberían producirse.
9
A.Ortigosa POO - EPS - UAM 17
Requisito: Atrapar o Declarar
Un método debe o bien atrapar o biendeclarar todas las excepciones comprobadasque pueden ser lanzadas por ese método. Clases de excepciones. Lanzamiento de excepciones. Capturar excepciones. Declarar (relanzar) excepciones.
A.Ortigosa POO - EPS - UAM 18
Captura de excepciones (I)
El primer paso para construir un manejadorde excepciones es encerrar las sentencias quepueden lanzar una excepción en un bloquetry:
try{// sentencias que pueden producir excepción
}
10
A.Ortigosa POO - EPS - UAM 19
Captura de excepciones: ejemplo
public class ListOfNumbers {private Vector victor;private static final int SIZE = 10;
...public void writeList() {
PrintWriter out = null;try {
out= new PrintWriter(new FileWriter("OutFile.txt"));for (int i = 0; i > SIZE; i++) {
out.println("Value at: " + i + " = " +victor.elementAt(i));
}}out.close();
}}
A.Ortigosa POO - EPS - UAM 20
Captura de excepciones (II)
Las excepciones que se produzcan en un bloque tryson tratadas por un manejador de excepcionesasociado.
Para asociar manejadores de excepciones a unbloque try, se usan sentencias catch.
try{...
} catch (TipoExcepcion nombre){...
} catch (TipoExcepcion nombre){...
} ...
manejador deexcepciones
11
A.Ortigosa POO - EPS - UAM 21
Captura de excepciones (II)
Cada bloque catch declara el tipo de excepción quepuede manejar. Debe ser el nombre de una clase que herede de
Throwable. El RTS invoca el primer bloque catch (en la pila de
ejecución) cuyo TipoExcepcion coincida con el tipode la excepción a tratar. La excepción a tratar puede ser asignada al argumento
del manejador de excepciones.
A.Ortigosa POO - EPS - UAM 22
Captura de excepciones (II):ejemplo
try {...
} catch (FileNotFoundException e) {System.err.println("FileNotFoundException: " + e.getMessage());throw new RuntimeException(e);
} catch (IOException e) {System.err.println("Caught IOException: " + e.getMessage());
}
12
A.Ortigosa POO - EPS - UAM 23
Captura de excepciones (III)
El paso final de un manejador de excepciones es lalimpieza final antes de ceder el control.
Para esto, se cierra el código con un bloque finally. Este bloque es opcional y provee un mecanismo
para terminar ordenadamente, independientementede lo que haya sucedido en el bloque try.
A.Ortigosa POO - EPS - UAM 24
Bloque finally: ejemplo
try {...out.close(); // don't do this; it duplicates code
} catch (FileNotFoundException e) {out.close(); // don't do this; it duplicates codeSystem.err.println("Caught: FileNotFoundException: " + e.getMessage());throw new RuntimeException(e);
} catch (IOException e) {System.err.println("Caught IOException: " + e.getMessage());
}
13
A.Ortigosa POO - EPS - UAM 25
Bloque finally: ejemplo
finally { if (out != null) {
System.out.println("Closing PrintWriter"); out.close();
} else { System.out.println("PrintWriter not open");
} }
A.Ortigosa POO - EPS - UAM 26
Requisito: Atrapar o Declarar
Un método debe o bien atrapar o biendeclarar todas las excepciones comprobadasque pueden ser lanzadas por ese método. Clases de excepciones. Lanzamiento de excepciones. Capturar excepciones. Declarar (relanzar) excepciones.
14
A.Ortigosa POO - EPS - UAM 27
Declarar las excepciones lanzadas
A veces no conviene que una excepción seatratada donde se produce, sino que es mejorque la trate un método “superior” de lacadena.
Entonces el método “deja pasar” o “relanza”la excepción.
El tipo de excepción debe ser declarado en lacabecera.
A.Ortigosa POO - EPS - UAM 28
Declarar las excepciones lanzadas
Un método debe declarar los valores quepuede devolver (tipo) y las excepciones quepuede arrojar (tipo).
Se declara en la cabecera del método. Ejemplo:
public String readLine() throws IOException
15
A.Ortigosa POO - EPS - UAM 29
Declarar las excepciones lanzadas:ejemplo
publicvoidwriteList()throwsIOException,ArrayIndexOutOfBoundsException{
...
A.Ortigosa POO - EPS - UAM 30
Las excepciones son partede la interfaz de un objeto
Sólo los Error's y las RuntimeException's no requieren ser declarados Un método sobreescrito no puede declarar más excepciones que
(subclases de) las que declara la definición en la clase padre Si un método sobreescrito emite una excepción no declarada en el padre,
es obligatorio procesarla aunque no se haga nada con ellaclass X extends Applet { public void start () { // start heredado de Applet try { ... } (catch IOException e) { /* vacio */} }} Normalmente es
preferible tratarla,no ignorarla
16
Tratamiento de excepciones
Tratamiento avanzado
A.Ortigosa POO - EPS - UAM 32
Lanzamiento de Excepciones
¿Qué pasa cuando no existe una excepciónapropiada? Se crea una clase propia, derivada de Exception o
de cualquier de sus hijos. Es habitual suministrar constructor sin
argumentos y otro que reciba un mensajedetallado (visible a través de toString).
17
A.Ortigosa POO - EPS - UAM 33
Definición de clases paraexcepciones
La superclase Throwable define dos constructores: Throwable() Throwable(String description)
class SaldoInsuficiente extends Exception { SaldoInsuficiente (long num, long s) { super("La cuenta " + numcuenta + " no tiene saldo suficiente:" + saldo); }}
class CuentaBloqueada extends Exception { public CuentaBloqueada(long numcuenta) { super("La cuenta " + numcuenta + " está bloqueada"); }}
A.Ortigosa POO - EPS - UAM 34
Captura y procesamiento deexcepciones
static public void main (String args[]) { try { new CuentaBancaria () .retirar (100000); } catch (SaldoInsuficiente excep) { System.out.println (excep.toString ()); } catch (CuentaBloqueada excep) { System.out.println (excep. toString ()); }}
Se ejecuta el primercatch de tipo compatible
Y podríaseguirejecutando
18
A.Ortigosa POO - EPS - UAM 35
Jerarquías de excepciones
SaldoInsuficiente CuentaBloqueada
ExcepcionBanco
...Tratamiento genérico
catch (ExcepcionBanco obj) { ...}
Tratamiento específico
catch (SaldoInsuficiente obj) { ...}catch (CuentaBloqueada obj) { ...}
A.Ortigosa POO - EPS - UAM 36
¿Y si no se captura una excepción?
public static void main(String[] args) throws CuentaBloqueada, SaldoInsuficiente { CuentaBancaria cb = new CuentaBancaria(5000);
cb.retirar(10000);}
Se debe (re)lanzar (o “dejar pasar”)
Aborta la ejecución
19
A.Ortigosa POO - EPS - UAM 37
¿Y si no se captura una excepción?
¿Y si tampoco se deja pasar? public static void main(String[] args) { CuentaBancaria cb = new CuentaBancaria(5000);
cb.retirar(10000);}
Error decompilación
A.Ortigosa POO - EPS - UAM 38
Excepciones predefinidas
Java genera los errores de ejecución en forma deexcepciones
Runtime exceptions: punteros null, arrays,aritmética, etc. No se comprueban En general, no deben subclasificarse
Error: errores de vinculación, desbordamiento dememoria, etc. (errores serios) En general no deben procesarse ni subclasificarse
20
A.Ortigosa POO - EPS - UAM 39
Algunas clases de excepciones
AWTException
Exception
Definidas porel programadorIOExceptionAWTException Runtime
Exception
EOFException
FileNotFoundException
EmptyStackException
IndexOutOfBoundsException
NullPointerException
ArithmeticExceptionClassCastException
A.Ortigosa POO - EPS - UAM 40
Métodos de Throwable
Throwable() y Throwable(String) getMessage()
Devuelve el mensaje del objeto
toString() Devuelve un String incluyendo la clase del objeto más el mensaje
getStackTrace() Retorna una lista con la traza de ejecución
printStackTrace() Escribe la traza de ejecución en el standard errorCuando una excepción no se procesa hasta el final, el programa se
interrumpe y se ejecuta printStackTrace()
21
A.Ortigosa POO - EPS - UAM 41
Ventajas de las excepciones
Separación del tratamiento de errores del resto del códigodel programa Evitar manejo de códigos de error Evitar la alteración explícita del control de flujo
Propagación de errores a través de la pila de llamadas amétodos Evitar el retorno de valores de error Evitar la utilización de argumentos adicionales
Agrupamiento de tipos de errores, diferenciación de tipos deerrores Jerarquías de clases de excepciones Tratar los errores al nivel de especificidad deseado
A.Ortigosa POO - EPS - UAM 42
Sin tratamiento de errores
readFile { open the file; determine its size; allocate that much memory; read the file into memory; close the file;}
22
A.Ortigosa POO - EPS - UAM 43
Tratamiento de erroressin excepciones
errorCodeType readFile { initialize errorCode = 0; open the file; if (theFileIsOpen) { determine the length of the file; if (gotTheFileLength) { allocate that much memory; if (gotEnoughMemory) { read the file into memory; if (readFailed) errorCode = -1; } else errorCode = -2; }
else errorCode = -3;
close the file;
if (theFileDidntClose && errorCode == 0)
errorCode = -4;
else errorCode = errorCode & -4;
}
else errorCode = -5;
return errorCode;
}
A.Ortigosa POO - EPS - UAM 44
Tratamiento de errorescon excepciones
readFile { try { open the file; determine its size; allocate that much memory; read the file into memory; close the file; } catch (fileOpenFailed) { doSomething; } catch (sizeDeterminationFailed) { doSomething; } catch (memoryAllocationFailed) { doSomething; } catch (readFailed) { doSomething; } catch (fileCloseFailed) { doSomething; }}
23
A.Ortigosa POO - EPS - UAM 45
Sin tratamiento de errores
method1 { call method2;}
method2 { call method3;}
method3 { call readFile;}
A.Ortigosa POO - EPS - UAM 46
Tratamiento de erroressin excepciones
method1 { errorCodeType error; error = call method2; if (error) doErrorProcessing; else proceed;}
errorCodeType method2 { errorCodeType error; error = call method3; if (error) return error; else proceed;}
errorCodeType method3 { errorCodeType error; error = call readFile; if (error) return error; else proceed;}
24
A.Ortigosa POO - EPS - UAM 47
Con excepciones
method1 { try { call method2; } catch (exception) { doErrorProcessing; }}
method2 throws exception { call method3;}
method3 throws exception { call readFile;}
A.Ortigosa POO - EPS - UAM 48
Excepciones encadenadas
Un método puede convertir una excepciónque recibe en otra Para mantener la interfaz del método Para mantener el nivel de abstracción requerido
Para esto, crea una nueva excepción queencapsula (Design Pattern: Adapter) laoriginal
25
A.Ortigosa POO - EPS - UAM 49
Excepciones encadenadas
Para encapsular:catch (OldException oldE){
NewException newE = new NewException (oldE);throw(newE);
}
Ej: RuntimeException unchecked = new RuntimeException (checked).
Para utilizar excepción original:Throwable t = newE.getCause()
La información no se pierde.
A.Ortigosa POO - EPS - UAM 50
Excepciones encadenadas
Soporte de Throwable: public Throwable(Throwable cause) public Throwable(String message,
Throwable cause) public Throwable getCause() public Throwable initCause(Throwable cause)
26
A.Ortigosa POO - EPS - UAM 51
Recapitulando
Ejemplo de excepción comprobada: El método add de la interfaz Collection es
opcional. La forma de especificar esto es decir que el
método puede lanzar la excepciónUnsupportedOperationException si la clase noimplementa el método.
A.Ortigosa POO - EPS - UAM 52
Documentación (parcial) deCollection
27
Concurrencia e Hilos
Programación basada en hilos.Planificación de hilos.
A.Ortigosa POO - EPS - UAM 54
Hilos
El objetivo de los hilos es, mientras se está ejecutando unatarea, darle oportunidad a otras de ejecutarse. Una aplicación Java sin hilos (o mejor dicho, con un solo hilo) se
puede pensar con un sistema operativo sin scheduler.
Típicamente utilizados en applets e interfaces gráficas
ejecución
28
A.Ortigosa POO - EPS - UAM 55
Hilos
Los hilos son instancias de clases que implementan Runnable Normalmente subclases de Thread.
En la clase de un hilo se debe definir el método run() Para ejecutar un hilo:
Crear un objeto de la clase del hilo Invocar el método start() start hace que se ejecute el método run() run típicamente consiste en un bucle
Las clases Thread y Object proporcionan métodos paragestionar y sincronizar los hilos
A.Ortigosa POO - EPS - UAM 56
Vida de los hilos
main
run
objetos, no clases!!
4
29
A.Ortigosa POO - EPS - UAM 57
Vida de los hilos (II)
main
run
run
A.Ortigosa POO - EPS - UAM 58
Creación de un hilo: la claseThread
class Repeticion extends Thread { private int repeticiones; private String mensaje; Repeticion (String msg, int n) { mensaje = msg; repeticiones = n; } public void run () { for (int i = 1; i <= repeticiones; i++) System.out.println (mensaje + " " + i); }} public static void main (String args[]) {
Repeticion r1 = new Repeticion ("Rojo", 5); Repeticion r2 = new Repeticion ("Azul", 80); r1.start (); r2.start ();}
Recién aquí se invocaal método run()
30
A.Ortigosa POO - EPS - UAM 59
Ejecución de hilos concurrentes
A.Ortigosa POO - EPS - UAM 60
¿Qué pasa si...?
class Repeticion extends Thread { ... public void metodo() { ... }}
public static void main (String args[]) { Repeticion r1 = new Repeticion ("Rojo", 5); ... r1.metodo(); ...}
El “metodo”, se ejecutaen otro thread?
NO
31
A.Ortigosa POO - EPS - UAM 61
La interfaz Runnable
No siempre es posible o conveniente que laclase que ejecuta el hilo herede de la claseThread La herencia no representa relación es-un La clase debe heredar de otra
En realidad, lo único obligatorio es queimplemente la interfaz Runnable
A.Ortigosa POO - EPS - UAM 62
La interfaz Runnable
class Repeticion2 implements Runnable { private int repeticiones; private String mensaje; Repeticion2 (String msg, int n) { mensaje = msg; repeticiones = n; } public void run () { for (int i = 1; i <= repeticiones; i++) System.out.println (mensaje + " " + i); }}
32
A.Ortigosa POO - EPS - UAM 63
Cuando la clase hereda deRunnable
Aún es necesario crear una instancia de Thread que lo lance
O mejor aún, para conservar la interfaz de Thread
public static void main (String args[]) { Repeticion r1 = new Repeticion ("Rojo", 5); Thread t = new Thread (r1); t.start ();}
class Repeticion2 implements Runnable {...
public void start () { runner = new Thread (this); runner.start ();
}
A.Ortigosa POO - EPS - UAM 64
Planificación de hilos
En Java, depende de la implementación: En Solaris o Linux, con implementación “green
threads”, un hilo no se interrumpe si el no quiere Acapara tiempo de procesador y no permite a otros
hilos realizar su trabajo En Windows, o con los “threads nativos” de
Java (implementados en la VM), el sistemarealiza “división de tiempo” (de procesador)
33
A.Ortigosa POO - EPS - UAM 65
Planificación de hilos
Con una implementación “green threads”, si el hilono se bloquea (ej: I/O), sigue ejecutando hasta quetermine Esto puede variar cuando hay diferentes prioridades
Para asegurar que, independientemente de laplataforma de ejecución, un hilo no es “egoísta” sleep() yield()
A.Ortigosa POO - EPS - UAM 66
Método sleep()
Si el thread debe esperar por algo, en vez deespera ocupada, invocamos a sleep()
if (egoista) {//esperar 5 milisegundoslong t = System.currentTimeMillis();while (System.currentTimeMillis() < t + 5) ;
}else{
sleep(5);}
• static void sleep(long milisegundos)
34
A.Ortigosa POO - EPS - UAM 67
Método yields()
Cuando al hilo en realidad no le hace faltaesperar static void yield()
Hace que el hilo en ejecución “se rinda” Si existen otros hilos (con prioridad igual o
mayor), serán planificados a continuación
A.Ortigosa POO - EPS - UAM 68
Prioridad de hilos
Asignación de una prioridad: setPriority (int) Thread.MIN_PRIORITY 1 Thread.NORM_PRIORITY 5 Thread.MAX_PRIORITY 10
Un hilo deja de ejecutarse sólo cuando: El hilo deja de ser runnable Se arranca otro hilo de mayor prioridad En algunos sistemas operativos, cuando el planificador activa otro
hilo de igual prioridad
Dependencia del sistema operativo No es el camino para ordenar o sincronizar hilos
35
Concurrencia e Hilos
Estados de un hilo.Sincronización de hilos.
A.Ortigosa POO - EPS - UAM 70
Estados de un hilo
runnable(ejecutable)
not started(nuevo)
not runnable(bloqueado)
dead(muerto)
stop
start
Ejecutar un hilo es ejecutar su método run
El thread muere por stop (censurado)o cuando run terminao por una excepción no capturada
sleep fin tiempo
E/S completa
36
A.Ortigosa POO - EPS - UAM 71
Muerte de un hilo: saliendo derun
class Hilo extends Thread { boolean seguir; public void run () { seguir = true; while (seguir) { ... } }}
public static void main (String args[]) { Hilo h = new Hilo (); h.start (); ... h.seguir = false;}
A.Ortigosa POO - EPS - UAM 72
Métodos para gestionarel estado de un hilo
Runnable run ()
Thread implements Runnable start () stop () // CENSURADO sleep (long) suspend() // CENSURADO boolean isAlive()
...
37
A.Ortigosa POO - EPS - UAM 73
Interrupción de hilos
Un hilo termina cuando su método runretorna.
¿Cómo puedo hacer para terminarlo antes? En versiones anteriores se le enviaba un mensaje
stop() CENSURADO. Ahora no es fácil, pero se le puede solicitar que
finalice con el mensaje interrupt(). El método run deberá comprobar periódicamente
si le han solicitador terminar.
A.Ortigosa POO - EPS - UAM 74
Comprobando si debe salir
public void run() {...while (no hay petición de terminar && queda trabajo){
seguir trabajando;}// salir del método run y terminar el hilo
}
Thread t;...t.interrupt();
38
A.Ortigosa POO - EPS - UAM 75
Interrumpiendo hilos suspendidos
El hilo puede estar “dumiendo” o “esperando” sleep() o wait().
Se genera una excepción InterruptedException
Se termina el bloqueo (despierta el hilo). No es un requisito que el hilo termine
La interrupción sólo llama la atención del hilo Se decide qué hacer en una cláusula catch
A.Ortigosa POO - EPS - UAM 76
Interrumpiendo hilos suspendidos
public void run() { try {
while (queda trabajo por hacer){seguir trabajando;
} catch(InterruptedException exception){
// el hilo fue interrumpido durante sleep o wait } finally {
//limpiar, en caso de ser necesario } // salir del run y terminar el thread}
39
A.Ortigosa POO - EPS - UAM 77
¿Y si el hilo no estaba dormido?
La excepción InterruptedException sólo se generasi el hilo estaba “durmiendo” o “esperando”. Si el hilo estaba bloqueado en E/S, la excepción NO es
generada y las operaciones no son finalizadas El hilo debe llamar al método interrupted para
saber si ha sido interrumpido recientementewhile (!interrupted() && queda trabajo por hacer){
seguir trabajando}
A.Ortigosa POO - EPS - UAM 78
Dos formas de comprobar
static boolean interrupted() Comprueba si el hilo actual (el que está
ejecutando la instrucción) ha sido interrumpido.Reinicializa el estado de interrumpido del hiloactual.
boolean isInterrupted() Comprueba el si el receptor ha sido
interrumpido. No cambia la condición de“interrumpido” del hilo
40
A.Ortigosa POO - EPS - UAM 79
Evitando excepción
Si el método no puede disparar la excepcióntry{ ... sleep(delay); ...}catch (InterruptedException exception){ Thread.currentThread().interrupt();}
No dejar vacío!!
• static Thread currentThread ()
A.Ortigosa POO - EPS - UAM 80
Evitando comprobación
Si lo que queremos es evitar poblar el códigode if (isInterrupted())If (isInterrupted()) throw new InterruptedException(); El código debe estar preparado para finalizar el
run cuando se produzca la interrupción El correspondiente método debe declarar
throws InterruptedException
41
A.Ortigosa POO - EPS - UAM 81
Problema con hilos concurrentes
Interferencia:
O peor aún
Solución: Exclusión Mutua
saldo = saldo - retiro;
if (saldo > retiro)saldo = saldo - retiro;
A.Ortigosa POO - EPS - UAM 82
Exclusión mutua:métodos synchronized
Evitar interferencias entre hilos que manipulan unmismo objeto
Métodos synchronized de un mismo objeto nopueden ejecutarse a la vez en hilos concurrentes
El primer hilo que invoca uno de los métodosbloquea el objeto
Los demás hilos que llamen al método quedanbloqueados mientras tanto
42
A.Ortigosa POO - EPS - UAM 83
Exclusión mutua en objetos
Sin exclusión mutua:
if (saldo > retiro)saldo = saldo - retiro
Cuenta Bancaria
A.Ortigosa POO - EPS - UAM 84
Exclusión mutua en objetos
Con exclusión mutua:
if (saldo > retiro)saldo = saldo - retiro
bloqueado
sincronizado
Cuenta Bancaria
43
A.Ortigosa POO - EPS - UAM 85
Exclusión mutua:métodos synchronized
El primer hilo desbloquea el objeto cuando: Termina Se detiene con sleep o wait
En ese momento los demás hilos compiten porcontinuar Sólo uno lo consigue Los demás vuelven a quedar en espera
synchronized también se puede aplicar a bloquesde código
A.Ortigosa POO - EPS - UAM 86
Exclusión mutua: ejemplo
class Plaza { Pasajero pasajero = null; boolean reservada () { return pasajero == null; } void reservar (Pasajero p) { pasajero = p; }}
class Vuelo { Plaza plazas[]; Vuelo (...) { ... } synchronized void reservar (Pasajero p) { for (int i = 0; i < plazas.length; i++) if (!plazas[i].reservada ()) plazas[i].reservar (p); }}
44
A.Ortigosa POO - EPS - UAM 87
Exclusión mutua: ejemplo
class TerminalVenta extends Thread { public void run () { Vuelo v; Pasajero p; ... v.reservar (p); ... }}
public static void main (String args[]) { TerminalVenta t1 = new TerminalVenta (...); TerminalVenta t2 = new TerminalVenta (...); t1.start (); t2.start ();}
A.Ortigosa POO - EPS - UAM 88
Exclusión mutua: ejemplo
synchronized void reservar (Pasajero p) { ...
public static void main (String args[]) { TerminalVenta t1 = new TerminalVenta (...); TerminalVenta t2 = new TerminalVenta (...); t1.start (); t2.start ();
Vuelo
TerminalVenta
start(){...v.reservar
TerminalVenta
start(){...v.reservar
45
A.Ortigosa POO - EPS - UAM 89
Exclusión mutua a nivel bloque
¿Qué pasa si el método a utilizar no es sincronizado?
class TerminalVenta extends Thread { public void run () { Vuelo v; Pasajero p; ... // Si reservar no es synchronized synchronized (v) { v.reservar (p); } ... }}
A.Ortigosa POO - EPS - UAM 90
Sincronizados=Objetos
synchronized void reservar (Pasajero p) { ...
public static void main (String args[]) { TerminalVenta t1 = new TerminalVenta (...); TerminalVenta t2 = new TerminalVenta (...); t1.start (); t2.start ();
Vuelo
TerminalVenta
start(){...v.reservar
TerminalVenta
start(){...v.reservar
synchronized void reservar (Pasajero p) { ...
Vuelo
46
A.Ortigosa POO - EPS - UAM 91
Coordinación de hilos
Los métodos sincronizados sólo me proveenun mecanismo de exclusión mutua.
Es posible utilizar métodos sincronizadospara implementar coordinación de hilos wait notify notifyAll
A.Ortigosa POO - EPS - UAM 92
Coordinación de hilos: ejemplo
En lugar de:
queremos esperar a que haya fondos
if (saldo > retiro)saldo = saldo - retiro;
while (saldo < retiro) {// esperar
}saldo = saldo - retiro;
47
A.Ortigosa POO - EPS - UAM 93
Coordinación de hilos: ejemplo
Pero hay que recordar que esto está en un métodosincronizado:
Mientras estoy esperando que aumente el saldo,nadie más puede entrar a modificar la cuenta!! Interbloqueo
synchronized void retirar (long retiro) {while (saldo < retiro) {
// esperar, no hacer nada}saldo = saldo - retiro;
}
A.Ortigosa POO - EPS - UAM 94
Uso del wait
Solución: usar el wait() para esperar
Cuando se usa el wait dentro de un métodosincronizado, el hilo actual se bloquea y libera elbloqueo del objeto
synchronized void retirar (long retiro) {while (saldo < retiro) {
wait();}saldo = saldo - retiro;
}
48
A.Ortigosa POO - EPS - UAM 95
Uso del wait
Precaución: Una llamada al wait sólo desbloquea el objeto
dentro del cual es hecha. Si el hilo tiene otrosobjetos bloqueados, estos objetos permanecenbloqueados aunque el hilo no este ejecutable.
wait()
permanece bloqueado es liberado
A.Ortigosa POO - EPS - UAM 96
Despertando del wait
Cuando llama al método wait, el hilo quedafuera de la consideración del planificador Entra en lista de espera y tiene que ser retirado
de allí para poder seguir ejecutando (o al menospara ser considerado por el planificador)
Otro hilo debo invocar al método notify onotifyAll en el mismo objeto
49
A.Ortigosa POO - EPS - UAM 97
Despertando del wait
NotifyAll: Elimina todos los hilos de la lista de espera del objeto.
Notify: Elimina uno elegido arbitrariamente (no tenemos ningún
control sobre la elección). Si es elegido por el planificador, el hilo intentará
entrar de nuevo en el objeto y continuar donde dejóen la llamada al wait.
A.Ortigosa POO - EPS - UAM 98
Uso del notifyAll
synchronized void retirar (long retiro) {while (saldo < retiro) {
wait();}saldo = saldo - retiro;
}
synchronized void depositar (long deposito) {saldo = saldo + deposito;// por si hay alguien esperandonotifyAll();
}
50
A.Ortigosa POO - EPS - UAM 99
Uso del wait y notify
Es extremadamente importante que alguienllame al notify cuando hay un hilo esperando. El hilo no tiene forma de salir de la cola de
espera por si mismo, ni tampoco existemecanismo automático para hacerlo.
¿Cuándo llamar al notify? Siempre que cambiemos una condición por la
cual alguien puede estar esperando. No hay problema si nadie está esperando.
A.Ortigosa POO - EPS - UAM 100
Dormir un hilo: wait vs.sleep
wait
Se invoca sobre un Object
Sólo puede ser llamado desde unmétodo synchronized
Puede ser despertado con notifydesde otro método synchronizeddel mismo objeto
wait() termina por notify() wait(n) termina cuando transcurren
n mseg. o por notify()
sleep
Se invoca sobre un Threado sobre la clase Thread
No se puede despertar hasta quetermina
Termina después de un tiempo
51
A.Ortigosa POO - EPS - UAM 101
Estados de un hilo
runnable(ejecutable)
not started(nuevo)
not runnable(bloqueado)
dead(muerto)
stop
start
Ejecutar un hilo es ejecutar su método run
sleep fin tiempo
E/S completa
wait notify(All)
Bloqueo disponible
El thread muere por stop (censurado)o cuando run terminao por una excepción no capturada
A.Ortigosa POO - EPS - UAM 102
Terminar un hilo con stop
class Hilo extends Thread { public void run () { while (true) { ... } }}
public static void main (String args[]) { Hilo h = new Hilo (); h.start (); ... h.stop ();}
Deprecated !
Puede provocarinconsistencias
52
A.Ortigosa POO - EPS - UAM 103
Terminar un hilo con stop
De la documentación de Java:Deprecated. This method is inherently unsafe. Stopping a thread with Thread.stop causes it tounlock all of the monitors that it has locked (as a natural consequence of the uncheckedThreadDeath exception propagating up the stack). If any of the objects previously protected bythese monitors were in an inconsistent state, the damaged objects become visible to other threads,potentially resulting in arbitrary behavior. Many uses of stop should be replaced by code thatsimply modifies some variable to indicate that the target thread should stop running. The targetthread should check this variable regularly, and return from its run method in an orderly fashionif the variable indicates that it is to stop running. If the target thread waits for long periods (on acondition variable, for example), the interrupt method should be used to interrupt the wait.
A.Ortigosa POO - EPS - UAM 104
Dormir un hilo con suspend
class Hilo extends Thread { public void run () { while (true) { ... } }}
public static void main (String args[]) { Hilo h = new Hilo (); h.start (); ... h.suspend ();}
Deprecated !
Puede provocardeadlocks
53
A.Ortigosa POO - EPS - UAM 105
Dormir un hilo con suspend
De la documentación de Java:Deprecated. This method has been deprecated, as it is inherently deadlock-prone. If the targetthread holds a lock on the monitor protecting a critical system resource when it is suspended, nothread can access this resource until the target thread is resumed. If the thread that would resumethe target thread attempts to lock this monitor prior to calling resume, deadlock results. Suchdeadlocks typically manifest themselves as "frozen" processes.
A.Ortigosa POO - EPS - UAM 106
Algunos métodos de Thread
Thread.currentThread() start(), setPriority(), getPriority() setName(String), getName(), toString() setDaemon(boolean), isDeamon() sleep, yield(), interrupt(), interrupted(),
isInterrupted() isAlive() holdsLock(Object)
54
A.Ortigosa POO - EPS - UAM 107
Algunos métodos de Object
wait(), wait(long) notify(), notifyAll()
A.Ortigosa POO - EPS - UAM 108
Resumen
Los hilos se pueden crear extendiendo Thread oimplementando Runnable y definiendo run
Los métodos synchronized son mutuamente excluyentesentre sí para un mismo objeto
Con sleep, wait, notify, y utilizando prioridades, secoordinan los hilos
La interacción entre hilos es delicada, no hay una reglageneral: se resuelve considerando todas las combinacionesposibles
Es responsabilidad del programador evitar deadlocks