Índice • Excepciones • Genéricos • Colecciones Curso de Programación en Java – Interfaces: • Collection, Set, List, Queue, Map, SortedSet, SortedMap – Implementaciones • HashSet, ArrayList, LinkedList, HashMap, TreeSet, TreeMap – Algoritmos • Concurrencia – Threads Curso de programación en Java 1 Curso de programación en Java 2 Introducción (I) • La idea es separar el funcionamiento normal de un programa de la gestión de los errores. • Si algo va mal: Excepciones – División por cero. – No hay más memoria. – No existe el fichero deseado. • Se lanza una excepción que HAY que tratar. Curso de programación en Java 3 Curso de programación en Java Introducción (II) Sintaxis • El tratamiento de la excepción será distinto para cada caso, separando claramente lo que se debe hacer en cada caso • Si se puede recuperar del error continuará la ejecución normalmente, sino finaliza – Si no existe el fichero, pide otro nombre (bucle) – Si entrada en formato incorrecto, pide otro dato. Curso de programación en Java 4 5 • Se apoya en – try {...}: Abarca el programa normal. Si todo va bien será lo que ejecute. – throw exception: Cuando algo va mal nos permite lanzar una excepción para indicarlo. – catch (class exception) {…}: Nos permite tratar un tipo de excepción. Habrá un catch por cada tipo posible. – finally {…} Siempre se ejecuta, va al final. Curso de programación en Java 6 1 Paso de Excepciones entre funciones (I) Ejemplo try { // Codigo normal ... if (algo mal) throw excep; // Si fue mal esto no ejecutaria ... } catch (ArithmeticException e){...} // Excp. Aritm catch (InputMismatchException e) // Excp. formato catch (MyException) {...} //”mis” excep. finally {...} // Siempre se ejecuta • Si una función no captura una excepción está va a la función que la invocó, que saltará al “catch” correspondiente, así hasta el main • Si ninguna la captura se da una terminación anómala Exception in thread "main" java.lang.ArithmeticException: / by zero • Este esquema puede repetirse varias veces, consecutivas o en un bucle. Finalizado no debe haber errores por tratar Curso de programación en Java 7 Paso de Excepciones entre funciones (II) 8 Definir excepciones • Para indicar las excepciones que una función puede lanzar se ponen explicitamente: throws int pop () throws EmptyStackException {...} • Una función, dentro del catch, puede lanzar otra excepción (p.e. si no sabe tratar la 1ª) • E incluso relanzar la misma: throw e; Curso de programación en Java Curso de programación en Java 9 • Hay algunas predefinidas: – NoSuchFieldException, NoSuchMethodException, NullPointerException , IllegalArgumentException, ArrayIndexOutOfBoundsException, IOException, ClassNotFoundException • Incluso podemos definir nuestras Excep. class EmptyStackException extends Exception { EmptyStackException(String s) { super(s); } } Curso de programación en Java 10 Errores Aserciones (I) • Similar idea a las excepciones, pero son fallos que • Similar idea a las excepciones, pero detectan fallos del programador. • Toda función necesita que se cumplan unas premisas a la entrada (precondiciones) y deja el estado en un modo conocido (postcondiciones) • Si no se cumplen algo ha ido mal • Se activan en desarrollo y depuración, para no penalizar las ejecuciones “normales”: no están pensados para capturarse y tratarse: – OutOfMemoryError, VirtualMachineError • Se supone que son irrecuperables • En cambio todas las excepciones deberían capturarse para salir de forma “limpia” java –ea ejecutable Curso de programación en Java 11 Curso de programación en Java 12 2 Aserciones (II) • No están pensadas para ser tratadas (generan un AssertionError) Genéricos o Prototipos • No se tratan porque al ser errores de programación no deberían darse y si se dan no está claro como recuperarse assert(b!=0):“El divisor no puede ser cero"; • Genera: Exception in thread "main" AssertionError: El divisor no puede ser cero Curso de programación en Java 13 Templates Curso de programación en Java 14 Generics Introducción (I) Introducción (II) • Hay ciertos aspectos y características que son comunes a muchas clases. • Por ejemplo, estructuras de datos (pilas, listas, colas, árboles,...) o algoritmos (ordenar, invertir, sustituir) que pueden aplicarse a cualquier clase, no varía su significado. • Podemos tener una pila de enteros, de platos, de strings o de coches. • Podemos ordenar enteros, reales, complejos, strings,... Curso de programación en Java • Ejemplo: PILA. Definamos una pila de enteros: 15 Generics Curso de programación en Java 16 Generics Introducción (III) Introducción (IV) • La idea es programarlo una vez y no volver a tener que hacerlo • Aumenta la productividad ya que se reutiliza el código • Aumenta la calidad ya que se usa código “probado” • Permite centrarse en los aspectos importantes de nuestro programa • Debería incrementar la velocidad, una única implementación pero de calidad • ¡¡¡Otros ya lo han implementado por nosotros!!! Curso de programación en Java 17 • Además el compilador detecta errores que de otro modo no podría: Código más legible y robusto • Sea una caja para guardar objetos en general: public class Box { private Object object; public void add(Object object) { this.object = object; } public Object get() { return object; } } Curso de programación en Java 18 3 Generics Generics Introducción (V) Generics (I) • A la hora de usarla podemos tener problemas: // ONLY place Integer into this box! Box integerBox = new Box(); // Cast??? Integer someInt =(Integer) integerBox.get(); // MAL!!! integerBox.add("10"); // String!!!! • Esta mal pero el compilador no lo dice y luego se generará una “java.lang.ClassCastException: “ Curso de programación en Java • Volvamos con la pila de enteros ¿Qué sucede si ahora deseamos una pila de caracteres? • Necesitamos rehacer todo. Es absurdo. • Para esto están los prototipos o generics. Se aplican a clases, constructores, métodos,... • Se deja el tipo a utilizar como un argumento que luego se especificará. • No se genera una clase para cada nuevo tipo, todas son la misma. 19 Generics Curso de programación en Java 20 Generics Generics (II) // Sustituimos Object public class Box<T> { private T t; // T public void add(T { this.t = t; public T get() { return t; } } Generics (III) por T • A la hora de usarla se indica el tipo: Box<Integer> integerBox = new Box<Integer>(); is "Type" t) } • Beneficios claros: // Sin Cast!!! Integer someInt = integerBox.get(); // El compilador nos avisa que está mal!!! integerBox.add("10"); // String • T es un tipo “formal” que luego será sustituido por el tipo “real”. T se puede usar casi como cualquier tipo normal Curso de programación en Java • El compilador entiende que queremos hacer y nos da mejor soporte. 21 Generics Curso de programación en Java 22 Generics Generics (IV) Generics (V) • Se pueden usar también argumentos de tipo en métodos y constructores. En la clase Box<T>, con T Integer: public <U> void inspect(U u){ System.out.println("T: " + t.getClass().getName()); System.out.println("U: " + u.getClass().getName()); } • También se puede usar más de un argumento de tipo: T, U • Al usarlo: integerBox.inspect("some text"); T: java.lang.Integer U: java.lang.String Curso de programación en Java 23 • Normalmente en mayúsculas (para distinguirlos de los parámetros normales) y cortos (una letra): – E - Element – K - Key – N - Number – T - Type – V - Value – S,U,V etc. - 2nd, 3rd, 4th types Curso de programación en Java 24 4 Generics Generics Generics (VI) Tipos acotados • También con métodos estáticos. En la clase Box: public static <U> void fillBoxes(U u, List<Box<U>> boxes) { for (Box<U> box : boxes) { box.add(u); } } • Para restringir el tipo de dato que se pueda usar (bounded type parameters) se usa extends seguido de un tipo (o interfaz) que marca el límite superior • Al usarlo: Crayon red = ...; List<Box<Crayon>> crayonBoxes = ...; Box.<Crayon>fillBoxes(red, crayonBoxes); Box.fillBoxes(red, crayonBoxes); // Es igual. Curso de programación en Java public <U extends Number> void inspect(U u) { …} • U debe ser un subclase de Number, sino no compila. • Se pueden combinar varios: <U extends Number & MyInterface> 25 Generics Curso de programación en Java 26 Generics Subtipos Comodines (Wildcards) • Integer y Double son subtipos de Number, pero Box<Integer> y Box<Double> no de Box<Number> Box<Number> b = new Box<Number>(); b.add(new Integer(10)); // OK b.add(new Double(10.1)); // OK Box<? extends Number> b; public void boxEmpty(Box<?> b){} //También!! b = new Box<Integer>(); //Si Box.boxEmpty(new Box<String>()); // Si b.add(new Integer()); // NO b tipo real desc. public void boxEmpty(Box<Number> b){ … } Box.boxEmpty(new Box<Integer>()); //NO!!! Box.boxEmpty(new Box<Double>()); //NO!!! Curso de programación en Java • Para solucionar esto está los comodines “?”, que indica tipo desconocido. Se suele usar junto a modo acotado. • Caja de tipo desconocido subtipo de Number: 27 Generics Curso de programación en Java 28 Generics Borrado del tipo (I) Borrado del tipo (II) • Como se ha dicho, no se genera un clase para cada tipo, el compilador borra los argumentos de tipo y sólo hay una clase: Box<String> pasa a Box. • No se puede saber el tipo de una clase genérica durante la ejecución (Box es de raw type). if (item instanceof E) {…} // error E item2 = new E(); // error E[] iArray = new E[10]; // error • Los raw types se pueden usar, pero generan warnings ya que el compilador no puede chequear los tipos. • Es legal usarlo por compatibilidad con código antiguo • Si se usan mal generarán una excepción en tiempo de ejecución • Al generar las clases genéricas una única clase, no se puede usar el tipo formal en variables estáticas (debe haber una instancia para conocer el tipo real) E obj = (E)new Object(); //Unchecked cast war Curso de programación en Java 29 Curso de programación en Java 30 5 Generics Generics Borrado del tipo (III) Tipos Expandidos (I) • Una solución para E item2 = new E(); es usar literales de tipo clase. • Ahora java.lang.Class<T> es genérico y su método newInstance() devuelve T • Hay casos en que queremos mitigar cierta restricción de tipos, por ejemplo, para llamar a un método de una clase padre que admite algo menos restrictivo. Ejemplo sencillo: public static <T> void select(Class<T> c, String sqlStatement){ for (/* Iterate over jdbc results. */ ) { T item = c.newInstance(); result.add(item); } return result; } Curso de programación en Java interface Sink<T> { flush(T t); } public static <T> T writeAll(Collection<T> coll, Sink<T> snk) { T last; for (T t : coll) { last = t; snk.flush(last); } return last; } 31 Curso de programación en Java 32 Generics Generics Tipos Expandidos (II) Tipos Expandidos (III) • La solución es usar super. Es la inversa de extends, indica un supertipo de otro, Sink<? super T> Sink<Object> s; Collection<String> cs; String str = writeAll(cs, s); // Illegal • Tanto String como Object no encajan. Alternativa public static <T> T writeAll(Collection<? extends T>, Sink<T>) {...} ... // Call is OK, but wrong return type. String str = writeAll(cs, s); Curso de programación en Java • Es decir, recibe algo que es supertipo de T. En este caso será un Objeto, que es supertipo de String: public static <T> T writeAll(Collection<T> coll, Sink<? super T> snk) { ... } Sink<Object> s; Collection<String> cs; String str = writeAll(cs, s); // Yes! 33 Curso de programación en Java 34 Collections Introducción (I) • Como ya se ha dicho, hay estructuras de datos (pilas, listas, colas, árboles, hash,...) o algoritmos (ordenar, invertir, sustituir) que pueden aplicarse a muchas clases. • Apoyándose en los generics, se ha construido en java una biblioteca de estructuras de datos y algoritmos, muy útil. • ¡¡¡Otros ya lo han implementado por nosotros!!! • Las colecciones agrupan elementos (contenedores). Permiten añadir, borrar y manipularlos fácilmente. Colecciones (Biblioteca) Curso de programación en Java 35 Curso de programación en Java 36 6 Collections Collections Introducción (II) Interfaces (I) • Aumenta la productividad ya que se reutiliza el código • Aumenta la calidad ya que se usa código “probado” • Permite centrarse en los aspectos importantes de nuestro programa • Aumenta la velocidad, una implementación de calidad • La biblioteca está formada por: – Interfaces, que definen como debe comportarse un TAD – Implementaciones de estos interfaces – Algoritmo para trabajar con estos TAD List<String> listaNombres; • Deben usarse los interfaces, sin entrar en detalles de la implementación concreta. Curso de programación en Java • Todos estos contenedores son genéricos, pueden trabajar con cualquier tipo de objeto: • Cada interfaz tiene varias implementaciones que le dan soporte, el usuario elige la que más le conviene. • Debe usarse a través de la interfaz, no la implementación 37 Interfaces Curso de programación en Java 38 Interfaces Collections (I) public interface Collection<E> extends Iterable<E> { // Basic operations (a nivel de elementos) int size(); boolean isEmpty(); boolean contains(Object element); boolean add(E element); boolean remove(Object element); Iterator<E> iterator(); // Bulk operations (a nivel de la Colección) boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); boolean removeAll(Collection<?> c); boolean retainAll(Collection<?> c); void clear(); // Array operations Object[] toArray(); <T> T[] toArray(T[] a); } Curso de programación en Java Collections (II) • Representan grupos de objetos o elementos • Si se modifica devuelve true, sino false. • Dos formas de recorrerlos: – for-each – Iteradores: public interface Iterator<E> { boolean hasNext(); E next(); void remove(); } 39 Interfaces Curso de programación en Java 40 Interfaces Collections (III) Collections (IV) • for-each • Transformaciones a arrays para antiguas APIs for (Object o : collection) System.out.println(o); Object[] a = c.toArray(); // c collection of Strings String[] a = c.toArray(new String[0]); • Iteradores: c colección de E’s for(Iterator<E>it=c.iterator();it.hasNext(); ) if (!cond(it.next())) it.remove(); Curso de programación en Java 41 Curso de programación en Java 42 7 Interfaces Interfaces Set (I) • • • • Set (II) Representa Conjuntos. No permite elementos duplicados Mismos métodos que collection Tres implementaciones de propósito general • No usar la implementación: Set<String> uniques = new HashSet<String>(); Set<String> dups = new HashSet<String>(); for (String a : args) if (!uniques.add(a)) dups.add(a); // Destructive set-difference uniques.removeAll(dups); – HashSet: rápido, no guarda el orden. La usual. – TreeSet: más lento, ordena los elementos – LinkedHashSet: guarda el orden en que se insertaron • Permite operaciones de conjuntos: unión (addAll), intersección (retainAll), subconjuntos (containAll),… Curso de programación en Java • Con cambiar HashSet por TreeSet ya estaría ordenado!! 43 Interfaces Curso de programación en Java 44 Interfaces List (I) List (II) • • • • • • Es una secuencia ordenada, admite elementos duplicados Se puede acceder al elemento i-esimo (get y set) Se puede insertar/borrar a una posición add/remove Se puede buscar un elemento (indexOf) Se pueden obtener sublistas El iterador se ha mejorado y es bidireccional. El constructor admite la posición en la que empezar • Dos implementaciones generales: ArrayList, LinkedList Curso de programación en Java public interface List<E> extends Collection<E>{ // Positional access E get(int index); E set(int index, E element); boolean add(E element); // añade al final void add(int index, E element); E remove(int index); boolean addAll(int index,Collection<? extends E>c); int indexOf(Object o); // Search int lastIndexOf(Object o); // Search ListIterator<E> listIterator(); // Iteration ListIterator<E> listIterator(int index);//Iteration // Range-view [from,to), from:incl, to:excl List<E> subList(int from, int to); } 45 Interfaces Curso de programación en Java 46 Interfaces ListIterator Queue (I) public interface ListIterator<E> extends Iterator<E> { boolean hasNext(); E next(); boolean hasPrevious(); E previous(); int nextIndex(); int previousIndex(); void remove(); void set(E e); void add(E e); } Curso de programación en Java • Representan colas, por ejemplo, de trabajos (para la impresora, cpu o similar) • Pueden ser FIFO o LIFO. Hay colas con prioridades. • Existen versiones que, en situaciones críticas, lanzan excepciones o devuelven un valor especial, null, si pila vacía, llena: – Add-offer, remove-poll, element-peek • Dos implementaciones generales: LinkedList, PriorityQueue 47 Curso de programación en Java 48 8 Interfaces Interfaces Queue (II) Map (I) public interface Queue<E> extends Collection<E> { E element(); // no lo quita boolean offer(E e); //add al final E peek(); // no lo quita E poll(); // remove al principio E remove(); // remove al principio • Asocia a cada clave un valor. No puede haber claves repetidas. Es un conjunto de parejas (clave, valor) • Un ejemplo, un listín telefónico o una agenda • Tres implementaciones de propósito general: – HashMap, TreeMap, LinkedHashMap, análogo a Set • El valor puede ser cualquier cosa, inclusa una lista: Map<String, List<String>> map = new HashMap<String, List<String>>(); } Curso de programación en Java 49 Interfaces Curso de programación en Java 50 Interfaces Map (II) Map (III) public interface Map<K,V> {// Basic operations V put(K key, V value); V get(Object key); V remove(Object key); boolean containsKey(Object key); boolean containsValue(Object value); int size(); boolean isEmpty(); // Bulk operations void putAll(Map<? extends K, ? extends V> m); void clear(); // Collection Views (muy potente!!!) public Set<K> keySet(); public Collection<V> values(); public Set<Map.Entry<K,V>> entrySet(); } Curso de programación en Java // Interface for entrySet elements public interface Entry { K getKey(); V getValue(); V setValue(V value); } • Ejemplo for (KeyType key : map.keySet()) System.out.println(key); for (Map.Entry<KeyType, ValType> e : m.entrySet()) System.out.println(e.getKey() + ": " + e.getValue()); 51 Interfaces Curso de programación en Java 52 Interfaces SortedSet (I) SortedSet (II) • Conjunto ordenado según un orden natural o el criterio que proporcione la clase de los objetos guardados • Incluye subconjuntos (rangos), acceso al principio y final, al comparador. Los rangos son semi-abiertos // Borrar palabras que empiezan por ‘f’ dictionary.subSet("f", "g").clear(); • Una implementación general: TreeSet Curso de programación en Java 53 public interface SortedSet<E> extends Set<E> { // Range-view [from,to) from:incl, to:excl SortedSet<E> subSet(E fromElement, E toElement); SortedSet<E> headSet(E toElement); SortedSet<E> tailSet(E fromElement); // Endpoints E first(); E last(); // Comparator access Comparator<? super E> comparator(); } Curso de programación en Java 54 9 Interfaces Interfaces SortedMap (I) SortedMap (II) • Diccionario ordenado por las claves según un orden natural o el criterio que proporcione la clase de los objetos guardados • Incluye subconjuntos (rangos), acceso al principio y final, al comparador. Los rangos son semi-abiertos • Una implementación general: TreeMap Curso de programación en Java public interface SortedMap<K, V> extends Map<K, V>{ Comparator<? super K> comparator(); SortedMap<K, V> subMap(K fromKey, K toKey); SortedMap<K, V> headMap(K toKey); SortedMap<K, V> tailMap(K fromKey); K firstKey(); K lastKey(); } 55 Interfaces Curso de programación en Java 56 Interfaces Orden (I) Orden (II) • Ciertas clases admiten un orden natural, como los números, los Strings, las fechas (Date), ficheros o los caracteres • En otros casos debe definirse para cada clase. En personas puede ser según Apellidos y luego el nombre • En empleados puede ser la fecha de contratación • Para usar SortedSet y SortedMap los objetos deben poderse comparar, deben implementar Comparable y su único método compareTo(object o) Curso de programación en Java • int compareTo(object o) compara el objeto recibido por parámetro y el actual y devuelve negativo, cero o positivo si el parámetro es menor, igual o mayor que el actual (debe establecer un Orden Total) • Una alternativa a Comparable es Comparator<T> que tiene int compare(T obj1, T obj2) y funciona similar. • Se usa para clases que no implementan Comparable • Se pasa al Sort: <T> void sort(List<T> list, Comparator<? super T> c) 57 Implementaciones Curso de programación en Java 58 Implementaciones Introducción Set • Existen múltiples implementaciones que proporcionan la funcionalidad de cada interfaz. • La mayoría son generales, las hay especificas buscando características concretas. Y los usuarios pueden hacer las suyas a partir de implementaciones abstractas. • Otras son sincronizadas para permitir concurrencia. • Otras son mini-implementaciones, muy eficientes. • No debe hacerse el programa dependiente de la implementación elegida. Curso de programación en Java 59 • Set: Generales: – HashSet: rápida, no guarda el orden. La usual. Crece según necesidad. Se puede indicar tamaño inicial – TreeSet: más lenta, ordena los elementos – LinkedHashSet: guarda el orden en que se insertaron. También se puede indicar tamaño inicial. • Set: Específicas: – EnumSet: Para enumerados, muy eficiente (bit-vector) – CopyOnWriteArraySet: para conjuntos que se leen mucho y se escriben raramente. Todas las operaciones de escritura se hacen copiandolo, seguro con alta concurrencia. Curso de programación en Java 60 10 Implementaciones Implementaciones List Map • List: Generales: • Map: Generales: – ArrayList: rápida, tipo vector. Si inserta mucho al principio o se borran elemento, va mal. Puede indicarse tamaño inicial – LinkedList: guarda el orden en que se insertaron. Implementa también Queue. • List: Específicas: – HashMap: rápida, tipo vector. Si inserta mucho al principio o se borran elemento, va mal. Puede indicarse tamaño inicial – TreeMap: es ordenado siguiendo la clave. – LinkedHashMap: guarda el orden de inserción o según la clave • Map: Específicas: – CopyOnWriteArraySet: para listas que se leen mucho y se escriben raramente. Todas las operaciones de escritura se hacen copiandolo, seguro con alta concurrencia. – Si necesita concurrencia, usar Vector. Curso de programación en Java – – – – 61 Curso de programación en Java Implementaciones 62 Implementaciones Wrapper Implementations Queue • Añaden funcionalidad extra a ciertas implementaciones • Synchronization wrappers. Añaden sincronización. Para Collection, Set, List, Queue, Map, SortedSet, SortedMap • Se crean: Map<KeyType, ValType> m = Collections. • Queue: Generales: – LinkedList: rápida. – PriorityQueue: Colas con prioridad. synchronizedMap (new HashMap<KeyType, ValType>()); • Queue: Concurrentes, implementan BlockingQueue – – – – – EnumMap: Para claves enumeradas (es un array) WeakHashMap. Guarda referencias ‘debiles’, (sólo si se usan) IdentityHashMap. Se basa en “identidad” (objetos cambiantes). ConcurrentHashMap. Para el interfaz ConcurrentMap LinkedBlockingQueue. FIFO y acotada, nodos enlazados ArrayBlockingQueue. FIFO y acotada, un array PriorityBlockingQueue. Cola basada en prioridades no acotada DelayQueue. Cola de planificación basada en tiempo SynchronousQueue Curso de programación en Java • Todos los accesos deben accerse a través de esa variable • Los iteradores deben protegerse (son varios accesos) Set<KeyType> s = m.keySet(); synchronized(m) { // Synchronizing on m, not s! while (KeyType k : s) foo(k); } • Unmodifiable wrappers, para sólo lecturas. Para Collection, Set, List, Queue, Map, SortedSet, SortedMap 63 Curso de programación en Java Implementaciones 64 Algoritmos Mini Implementations Introducción • Array.asList. Da una vista del array como una lista. No puede cambiar de tamaño. Para lista de tamaño fijo. • Collections.nCopies. Una lista inmutable que contiene n copias de un mismo elmento. Para inicializaciones. • Collections.singleton. Un conjunto con un único elemento • emptySet, emptyList y emptyMap de Collections. Vacías. Curso de programación en Java 65 • • • • • • • Son métodos ‘estáticos’ y genéricos de Collections. La mayoría operan sobre listas. Sort. Ordena según orden natural o orden dado Shuffle. Baraja, usa Random. Manipulación de datos: reverse, fill, copy, swap, addAll binarySearch. Búsqueda. Sobre Collection: frecuency, disjoint, min, max Curso de programación en Java 66 11 Implementaciones Abstract Implementations • Esqueletos de implementaciones para facilitar a los usuarios sus propias implementaciones. • No suele ser necesario, siempre hay alguna implementación que nos viene bien. • Posibles razones: Concurrencia (Threads) – Implementar persistencia – Añadir funcionalidad – Específicas para ciertas aplicaciones • Hay versiones abstractas de las seis interfaces • Basta con implementar los métodos abstractos. Fácil. Curso de programación en Java 67 Curso de programación en Java Concurrencia 68 Concurrencia Introducción Threads (I) • Los computadores hacen varias cosas a la vez – Navegador, editores, procesador de textos, hojas de cálculo, compilador,… • Hoy en día, con varios núcleos, más aún. • Cada ejecución de un programa es un proceso • Un proceso es autocontenido, con todos los recursos que necesita para poder ejecutar. • Los procesos pueden cooperar usando IPC • Java permite lanzar nuevos procesos (ProcessBuilder) Curso de programación en Java • Un proceso puede tener varios threads • Estos threads comparten los recursos del proceso (memoria, ficheros,…), son más ligeros y eficientes • Java permite lanzar nuevos threads. Dos vías: – Implementar Runnable y su método Run: (new Thread(new ClassRunnable())).start(); – Extender Thread (también Run): (new ClassThread()).start(); • Además de crearlo debe lanzarse (start) 69 Curso de programación en Java Concurrencia 70 Concurrencia Threads (II) Funcionalidad de Threads • Extender Thread es más sencillo y proporciona métodos para conocer y manipular el thread, pero no puede heredar de otra clase. • Runnable es más flexible y permite además heredar de otra clase. Permite separar la tarea a realizar del thread que lo realizará • Al usar Thread surgen posible Excepciones Curso de programación en Java 71 • • • • sleep() nos permite suspende un thread (miliseg) Puede ser interrumpido por otro, interrupt() Se genera una Excepción (InterruptedException) Esa interrupción le indica que deje de hacer ‘algo’ para pasar a hacer otra cosa. • Si no estaba suspendido puede preguntar por interrupted() para saber si alguien le interrumpió • Se puede esperar por un thread, join(). Curso de programación en Java 72 12 Concurrencia Concurrencia Sincronización (I) Sincronización (II) • Los threads se comunican fácilmente, comparten toda la información (ven la misma memoria) • Pueden surgir problemas si no se coordinan al acceder a la información: Errores • Dos leen una variable A, la incrementan y la guardan. ¡¡¡Solo se ha incrementado en UNO!!! • Java proporciona synchronized para evitarlo • Cada objeto (y clase) tiene una “llave” o lock Curso de programación en Java • Una clase puede tener métodos sincronizados synchronized void metodo1() { …} synchronized void metodo2() { …} • No se pueden ejecutar a la vez invocaciones a métodos sincronizados de un mismo objeto • Si un thread ya está actualizando este objeto, cualquier otro thread deberá esperar a que termine el método que está ejecutando para poder ejecutar otro método sincronizado • Se implementa con cerrojos (lock) en cada objeto 73 Concurrencia Curso de programación en Java 74 Concurrencia Sincronización (III) Coordinación • Un thread debe adquirir este cerrojo para modificar el objeto y lo liberar al final. • Mientras nadie puede coger el cerrojo, esperan. • Se pueden sincronizar sentencias: • A veces un thread debe esperar que otro calcule algo: synchronized(this) {…} // especifica el obj. while (!data.isReady()) • Un thread puede adquirir un cerrojo que ya tiene, puede llamar a otros métodos sincronizados. • Si un thread 1 intenta adquirir el cerrojo de un objeto B desde un objeto A y otro thread 2 intenta adquirir el cerrojo de A desde B, se produce un interbloqueo. • La espera puede ser interrumpida • El otro thread le avisa con notify() o notifyAll() • Se debe usar en métodos sincronizados. Libera el cerrojo y luego lo vuelve a coger para examinar la condición. Curso de programación en Java while (!data.isReady()) 75 Concurrencia { “nada”; } • La cpu está ocupada para nada!!!! • Se puede decir que espere (wait). Libera la cpu. { wait(); } Curso de programación en Java 76 Concurrencia Cerrojos (intefaz lock) Ejecutores (intefaz Executor) • Se pueden crear y manipular directamente. • Solo un thread puede tener un cerrojo • Tiene una condition asociada para soportar wait, notify y notifyAll • Tiene: lock(), unlock() y tryLock() • Separan la tarea (task) a hacer del thread. • (new Thread(r)).start(); pasa a e.execute(r); • Si hay threads disponibles pone a ejecutar “r” (no crea el thread). Si no los hay, pone “r” como una tarea pendiente de ejecutar. • Con ExecutorService submit(), además de Runnable admite Callable (devuelve un valor) • Con ScheduledExecutorService se añade la posibilidad de indicar cuando ejecutará – Lock: coger la llave – Unlock: dejar la llave – Trylock: Si puedo cojo la llave, si no hago otra cosa Curso de programación en Java 77 Curso de programación en Java 78 13 Concurrencia Concurrencia Listas de threads (pool) Sincronización adicional • Da la opción de reutilizar los threads. Cuando acaban no se destruyen, se dejan por si luego hay una tarea que necesita ser ejecutada. Más rápido • Limita los recursos consumidos. • Los hay con un número de threads fijo (newFixedThreadPool), variable (newCachedThreadPool) o una tarea cada vez (newSingleThreadExecutor) • Bastante estructuras de datos de Collections tienen implementaciones concurrentes: BlockingQueue, ConcurrentMap, ConcurrentNavigableMap • Para facilitar el acceso a variable compartidas están los Atomic: AtomicInteger, AtomicBoolean, AtomicLong, AtomicReference Curso de programación en Java Curso de programación en Java 79 80 14