PROGRAMACION CONCURRENTE Y DISTRIBUIDA IV.3 Monitorización de excepciones en Threads J.M. Drake Notas: 1 Gestión excepciones en thread Java Las excepciones se pueden lanzar en cualquier punto de un programa Java. Cada método debe declarar las excepciones que potencial pueden ser lanzadas, y en consecuencia el desarrollador de la aplicación se ve obligado a decidir como atenderlas. Las excepciones que se derivan de la excepción RuntimeException (p.e. NullPointerException )no se requieren ser declaradas pueden ser lanzadas en cualquier punto. Las excepciones que no son atendidas, se propagan siguiendo la secuencia de invocaciones hasta que se alcanza el método main() en el que se manifiesta. Cuando la excepción no atendida se propaga sin ser atendida en un thread, se pierde al alcanzar el método run() sin manifestarse. Procodis’08: IV.3- Monitorización de excepciones en Threads Notas: 2 José M.Drake 2 Patrón Observer Su objetivo es establecer dinámicamente una dependencia entre un objeto Observer y otro Observable para que cuando en este se produzca una situación declara por el de interés pueda notificarla a todos los que se ha registrado como interesados en ella. Observer Observable Observer Event Observer Procodis’08: IV.3- Monitorización de excepciones en Threads Notas: 3 José M.Drake 3 Características de Observer-Observable La clase Observable es la que define las situaciones que pueden ser notificadas. A tal fin define la interfaz I_Observer en la que se declara el procedimiento notify con los parametros adecuados para manifestarla. La clase Observable no sabe estáticamente ni los objetos, ni las clases Observer que se van a interesar por las situaciones que va a notificar. La clase Observer se registra dinámicamente en el objeto Observable para hacerse destino de las notificaciones que en el futuro realice Observable. El único requisito que se le exige es que implemente la interfaz ObserverIF. La clase Observer define la respuesta que debe dar a las notificaciones que le sean hechas. Procodis’08: IV.3- Monitorización de excepciones en Threads Notas: 4 José M.Drake 4 Clases del patrón Observer <interface> I_Observer 0..n 1 <interface> I_Observable addObserver(theObserver) removeObserver(theObserver) notify(source,event) 0..n Observable Observer 1 1 Multicaster addObserver(:I_Observer) removeObserver(:I_Observer) notify(event) Procodis’08: IV.3- Monitorización de excepciones en Threads Notas: 5 José M.Drake 5 Interacciones entre objetos Procodis’08: IV.3- Monitorización de excepciones en Threads Notas: 6 José M.Drake 6 Problemas del patrón La distribución de las notificaciones puede requerir un tiempo muy alto: Porque hay muchos observadores. Porque cada notificación requiere una tonificación en cascada muy larga. Se pueden producir fallos por saturación del stack si se establecen notificaciones cíclicas. Puede evitarse introduciendo un flag en una de las clases de forma que cuando una notificación ya haya sido realizada una instancia, la cancele y no la siga transmitiendo Procodis’08: IV.3- Monitorización de excepciones en Threads Notas: 7 José M.Drake 7 Recursos Java para implementar el patrón Observer Java ofrece: La interfaz java.util.Observer public interface Observer{ public void update(Observable o, Object arg); //This method is called whenever the observed object is changed. // o - the observable object. // arg - an argument passed to the notifyObservers method } La clase “java.util.Observable” z This class represents an observable object. It can be subclassed to represent an object that the application wants to have observed z An observable object can have one or more observers. An observer may be any object that implements interface Observer. After an observable instance changes, an application calling the Observable's notifyObservers method causes all of its observers to be notified of the change by a call to their update method. z When an observable object is newly created, its set of observers is empty. Procodis’08: IV.3- Monitorización de excepciones en Threads Notas: 8 José M.Drake 8 Class Observable: methods (1) Constructor: Observable() // Construct an Observable with zero Observers. Métodos: void addObserver(Observer o) // Adds an observer to the set of observers for this // object, provided that it is not the same as some observer already in the set protected void clearChanged() //Indicates that this object has no longer changed, //or that it has already notified all of its observers of its most recent change, // so that the hasChanged method will now return false int countObservers() // Returns the number of observers of this Observable object. void deleteObserver(Observer o) // Deletes an observer from the set of observers // of this object. void deleteObservers() // Clears the observer list so that this object no longer has // any observers. boolean hasChanged() // Tests if this object has changed. Procodis’08: IV.3- Monitorización de excepciones en Threads Notas: 9 José M.Drake 9 Class Observable: methods (2) void notifyObservers() //If this object has changed, as indicated by the hasChanged method, // then notify all of its observers and then call the clearChanged method // to indicate that this object has no longer changed. void notifyObservers(Object arg) // If this object has changed, as indicated by the hasChanged method, // then notify all of its observers and then call the clearChanged method // to indicate that this object has no longer changed. protected void setChanged() // Marks this Observable object as having been changed; // the hasChanged method will now return true. Procodis’08: IV.3- Monitorización de excepciones en Threads Notas: 10 José M.Drake 10 Monitorización de excepciones en Thread import java.util.Observable; public class ThreadObservado extends Thread { public ObservableForThread o =new ObservableForThread(this); public void run(){ try{ int[] n= new int[10]; for(int i=0;i<=10;i++){ n[i]=i; } }catch(Exception e){ o.changes(); o.notifyObservers(e); } } } Procodis’08: IV.3- Monitorización de excepciones en Threads Notas: 11 José M.Drake 11 Clases ObservableForThread import java.util.Observable; public class ObservableForThread extends Observable{ Thread theThread; protected ObservableForThread(Thread t){ theThread=t; } public Thread getThread(){ return theThread; } protected void changes(){ this.setChanged(); } } Procodis’08: IV.3- Monitorización de excepciones en Threads Notas: 12 José M.Drake 12 Clase observadora import java.util.Observable; import java.util.Observer; public class ObservadorDeThreads implements Observer { public void update(Observable arg0, Object arg1) { String threadName=((ObservableForThread)arg0).getThread().getName(); System.out.println(“Detectada excepción "+((Exception)arg1).getMessage()+ " en objeto " + threadName); } public static void main(String[] args){ ObservadorDeThreads ode=new ObservadorDeThreads(); ThreadObservado t=new ThreadObservado(); t.o.addObserver(ode); t.setName("MiThreadObservado"); t.start(); try{ Thread.sleep(10000);}catch(InterruptedException e){}; } } Procodis’08: IV.3- Monitorización de excepciones en Threads Notas: 13 José M.Drake 13 Thread observado import java.util.Observable; public class ThreadObservado extends Observable implements Runnable{ public void run(){ try{ int[] n= new int[10]; for(int i=0;i<=10;i++){ n[i]=i; } }catch(Exception e){ this.setChanged(); this.notifyObservers(e); } } } Procodis’08: IV.3- Monitorización de excepciones en Threads Notas: 14 José M.Drake 14 Clase observadora import java.util.Observable; import java.util.Observer; public class ObservadorDeThreads implements Observer { public void update(Observable arg0, Object arg1) { System.out.println("Se ha detectado la excepción "+((Exception)arg1).getMessage()+ " en objeto " + arg0.toString());} public static void main(String[] args){ ObservadorDeThreads ode=new ObservadorDeThreads(); ThreadObservado r=new ThreadObservado(); Thread t=new Thread(r); r.addObserver(ode); t.start(); try{Thread.sleep(10000);}catch(InterruptedException e){}; } } Procodis’08: IV.3- Monitorización de excepciones en Threads Notas: 15 José M.Drake 15