05-java4

54
1 El lenguaje de programación JAVA Conceptos avanzados: Tratamiento de Excepciones Programación basada en Hilos Tratamiento de Excepciones Tratamiento básico

Transcript of 05-java4

Page 1: 05-java4

1

El lenguaje de programación JAVA

Conceptos avanzados:Tratamiento de Excepciones

Programación basada en Hilos

Tratamiento de Excepciones

Tratamiento básico

Page 2: 05-java4

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

Page 3: 05-java4

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

Page 4: 05-java4

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.

Page 5: 05-java4

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

Page 6: 05-java4

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.

Page 7: 05-java4

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

Page 8: 05-java4

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.

Page 9: 05-java4

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

}

Page 10: 05-java4

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

Page 11: 05-java4

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

}

Page 12: 05-java4

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

}

Page 13: 05-java4

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.

Page 14: 05-java4

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

Page 15: 05-java4

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

Page 16: 05-java4

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).

Page 17: 05-java4

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

Page 18: 05-java4

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

Page 19: 05-java4

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

Page 20: 05-java4

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

Page 21: 05-java4

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

Page 22: 05-java4

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

Page 23: 05-java4

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

Page 24: 05-java4

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

Page 25: 05-java4

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)

Page 26: 05-java4

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

Page 27: 05-java4

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

Page 28: 05-java4

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

Page 29: 05-java4

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

Page 30: 05-java4

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

Page 31: 05-java4

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

Page 32: 05-java4

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)

Page 33: 05-java4

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)

Page 34: 05-java4

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

Page 35: 05-java4

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

Page 36: 05-java4

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

...

Page 37: 05-java4

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

Page 38: 05-java4

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}

Page 39: 05-java4

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

Page 40: 05-java4

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

Page 41: 05-java4

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

Page 42: 05-java4

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

Page 43: 05-java4

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

Page 44: 05-java4

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

Page 45: 05-java4

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

Page 46: 05-java4

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;

Page 47: 05-java4

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;

}

Page 48: 05-java4

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

Page 49: 05-java4

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

}

Page 50: 05-java4

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

Page 51: 05-java4

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

Page 52: 05-java4

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

Page 53: 05-java4

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)

Page 54: 05-java4

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