Threads LSUB. 30 de marzo de 2016 GSYC

Documentos relacionados
Concurrencia en Android LSUB, GYSC, URJC

Introducción a Java LSUB. 30 de enero de 2013 GSYC

Programación Concurrente en Java: Threads. Ejemplos de programación concurrente. Luis Fernando Llana Díaz. 24 de abril de 2008

Colecciones de Java LSUB. 17 de febrero de 2016 GSYC

Normalmente, los programas son ejecutados de forma secuencial. Único flujo de control

Introducción a Java LSUB. 15 de enero de 2015 GSYC

Programación Orientada a Eventos

Hilos. Índice. Copyright Dept. Ciencia de la Computación e IA All rights reserved.

Concurrencia en Java

MONITORES EN JAVA. Antonio Tomeu Control de la Concurrencia en Java: API Estándar

Programación Concurrente en Java

Federico Peinado

TEMA 5: Control de la Concurrencia en Java (API Estándar)

1 HILOS (THREADS) EN JAVA

Threads. La plataforma JAVA soporta programas multhreading a través del lenguaje, de librerías y del sistema de ejecución. Dos.

Red LSUB. 4 de marzo de 2015 GSYC

Java: Programación Multithread

Otras formas de Sincronización en Java

Object 1. Threads en Java

Hebras y Sincronización en Java

Test : Conteste exclusivamente en una HOJA DE LECTURA ÓPTICA, no olvidando marcar que su tipo de examen es A.

MOM LSUB. 3 de abril de 2013 GSYC

Lenguaje de programación con JAVA

Concurrencia en Java

(THREADS) Ing. Laura Sandoval Montaño, Ing. Manuel Enrique Castañeda Castañeda PAPIME

75-62 Técnicas de Programación Concurrente II 2004 java Threads

Java Vademécum /concurrencia

UNIVERSIDAD CARLOS III DE MADRID DEPARTAMENTO DE INGENIERÍA TELEMÁTICA. Daniel Díaz Sánchez

TEMA 6: API Java para Concurrencia de Alto Nivel

Message Oriented Middleware: Java JMS

Concurrencia en Java

Tutorial de C# Delegados y Eventos. Por: Óscar López, M.Sc.

Programación Concurrente. Curso Java 2012, 2013 Juan Manuel Fernández Peña

Unidad Didáctica 2. Elementos básicos del lenguaje Java Tipos, declaraciones, expresiones y asignaciones

Anexo. Control de errores

Multitarea En Swing. Varios hilos trabajadores, también conocidos como hilos en segundo plano.

Programación Concurrente en Java

SUBPROGRAMAS PL/SQL César Martínez C. Profesor Instructor de Base de Datos Sede Puente Alto DUOC

Notas de clase. Threads

Programación Concurrente y de Tiempo Real Guión de prácticas 8: Monitores en Java (API. Natalia Partera Jaime Alumna colaboradora de la asignatura

Conceptos a tratar. Fundamentos de la Programación Orientada a Objetos Ampliación sobre clases y objetos

Sistemas Operativos: Programación de Sistemas. Curso Oscar Déniz Suárez Alexis Quesada Arencibia Francisco J.

Patrones de Diseño. Patrón estructural Composite. Técnicas de Programación - Curso 2007/08

T5-multithreading. Indice

CURSO DE PREPARACIÓN PARA LA CERTIFICACIÓN COMO PROGRAMADOR DE JAVA J2SE 5.0 DE SUN

Aplicaciones Concurrentes

Lenguajes de Programación Curso Práctica 4. Herencia. Utilización de interfaces y clases abstractas. 1. Interfaces Clases abstractas 2

INSTITUTO DE EDUCACIÓN SUPERIOR TECNOLÓGICO IBEROTEC SEMESTRE ACADÉMICO: 2014-II SÍLABO

Tema 4: Corrección y Robustez en C++ Programación Orientada a Objetos Curso 2008/2009 Begoña Moros Valle

TEMA 3. CONCEPTOS FUNDAMENTALES DEL NIVEL DEL SISTEMA OPERATIVO. Definición y objetivos de un S.O

Modelos de programación paralela y concurrente

1. Cuántas sentencias hay en la secuencia principal del siguiente programa?

LA ESTRUCTURA DE DATOS PILA EN JAVA. CLASE STACK DEL API JAVA. EJEMPLO Y EJERCICIOS RESUELTOS. (CU00923C)

INF 473 Desarrollo de Aplicaciones en Java

PROGRAMACION CONCURRENTE Y DISTRIBUIDA. III.3 Concurrencia con Java: Sincronización

Centro Asociado Palma de Mallorca. Antonio Rivero Cuesta

Multitarea en Java. Rafa Caballero - UCM

Derechos de Acceso: COMPOSICION

Introducción a Java (II) Dr. (c) Noé Alejandro Castro Sánchez

Tema 3. Programación orientada a objetos en Java (Parte 1)

LABORATORIO ARQUITECTURAS SOFTWARE DE VARIOS NIVELES EN JAVA (I)

GUIA No 5. CREACIÓN DE SubVI s

ÍNDICE. PRÓLOGO Parte I Parte II Apéndices... 23

INTERFACE COMPARATOR. DIFERENCIAS ENTRE COMPARATOR Y COMPARABLE. CLASE COLLECTIONS. EJERCICIOS RESUELTOS. (CU00918C)

Programación en Java. Programación en OO

LABORATORIO ARQUITECTURAS SOFTWARE DE VARIOS NIVELES EN JAVA (I)

INDICE Prefacio 1. Fundamentos de Java 2. Introducción a los tipos de datos y operadores

Concurrencia en.net David Jesús Horat Flotats

Principios de Computadoras II

Manipulación de procesos

Sockets. Los sockets son un mecanismo de comunicación entre procesos que se utiliza en Internet.

Hilos en Java. Crear un Hilo. Detener un hilo. Fuente:

Java nos ofrece la clase Thread y la interfaz Runable que permiten que varios procesos estén funcionando de forma concurrente.

Diseño de sistemas concurrentes

Sistemas operativos. Hasta ahora hemos visto. Relación programa-sistema operativo Gestión de memoria

de Gran Canaria Centro de Tecnología Médica Programación Concurrente

PROGRAMACIÓN ORIENTADA A OBJETOS CON JAVA

UNIVERSIDAD AUTÓNOMA DE BAJA CALIFORNIA FACULTAD DE CIENCIAS PRACTICA DE PROCESOS HERRAMIENTAS

Tema 2. El lenguaje de programación Java (Parte 1)

Sistemas Operativos. Daniel Rúa Madrid

CONCURRENCIA EN JAVA. Diseño de Sistemas Operativos Avanzados 2000/2001. Pedro Pablo Gómez Martín

Office 365 Pro Plus ACTVACIÓN EN EQUIPOS COMPARTIDOS

Herramientas Concurrentes en JAVA

Concurrencia y paralelismo

Procesos e Hilos en C

Monitores Ing. Iván Medrano Valencia

dit Real-Time Java Sistemas de Tiempo Real José F. Ruiz DIT/UPM UPM

Fundamentos de Ordenadores. Depurar programas usando Nemiver

Modulo 11. Clases y Objetos en Java

Tema 4. Excepciones en Java

GUIs en Java (3) Jose M. Peña

Tema 7.- Fundamentos de la Programación Orientada a Objetos

Lección 2: Creando una Aplicación en Java. 1. Estructura del archivo de una clase. 3. Definiendo clases fundamentos

Programación Orientada a Objetos. Java: Excepciones

Tema 2: Programas y procesos

EXAMEN FINAL Metodología y Programación Orientada a Objetos. Curso Cuatrimestre de otoño. 17 de Enero de 2011

Java y JVM: programación concurrente

Java RMI. las RPC de Java. Parte I. Luis Fernando Llana Díaz. Departamento de Sistemas Informáticos y ProgramaciónUniversidad Complutense de Madrid

Clases y Objetos en Java. ELO329: Diseño y Programación Orientados a Objetos

Sistemas Distribuidos. Soporte de Sistemas Operativos

Transcripción:

Threads LSUB GSYC 30 de marzo de 2016

(cc) 2015 Laboratorio de Sistemas, Algunos derechos reservados. Este trabajo se entrega bajo la licencia Creative Commons Reconocimiento - NoComercial - SinObraDerivada (by-nc-nd). Para obtener la licencia completa, véase http://creativecommons.org/licenses/. También puede solicitarse a Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. Las imágenes de terceros conservan su licencia original.

Threads Concurrencia? Un thread es un hilo de ejecución. Una aplicación tiene al menos un thread. Los threads de Java son expulsivos. La correspondencia entre threads y procesos del OS depende de la implementación. Antes de usar algo desde distintos threads debemos asegurarnos de que es thread-safe.

Thread La clase Thread proporciona la abstracción. Hay dos formas de crear una instancia de Thread: Crear una clase que derive de la clase Thread. Crear una clase que implemente la interfaz Runnable. Se recomienda usar esta aproximación: separar el trabajo (tu clase Runnable) del trabajador (la clase Thread). Además, puedes ser Runnable y extender otra clase distinta a Thread. El thread arranca cuando se invoca su método start().

Clase con interfaz Runnable p u b l i c c l a s s Tweeter implements Runnable { @ O v e r r i d e p u b l i c v o i d run ( ) { f o r ( i n t i = 0 ; i < 1 0 ; i ++) System. out. p r i n t l n ( Thread s a y s t w e e e e e t!!! ) ; p u b l i c s t a t i c v o i d main ( S t r i n g [ ] a r g s ) { f o r ( i n t i = 0 ; i < 1 0 ; i ++) ( new Thread ( new Tweeter ( ) ) ). s t a r t ( ) ;

Clase Thread anónima p u b l i c c l a s s S e r v i d o r { p u b l i c v o i d a t e n d e r ( ) { f i n a l Socket sk ; //... a c e p t a r l l a m a d a en sk... new Thread ( ) { p u b l i c v o i d run ( ) { s e r v i r C l i e n t e ( sk ) ; ;. s t a r t ( ) ; p r o t e c t e d v o i d s e r v i r C l i e n t e ( Socket sk ) { //...

Thread Thread proporciona varios métodos de clase interesantes: currentthread(): retorna la referencia al thread que está ejecutando. activecount(): retorna el número actual de threads activos. dumpstack(): vuelca la pila del thread actual en la salida de errores. sleep(int ms): causa que el thread actual se bloquee durante un tiempo. yield(): causa que el thread actual ceda su cuanto a otro thread. System. out. p r i n t l n ( Thread + Thread. c u r r e n t T h r e a d ( ). g e t I d ( ) + S t a t e + Thread. c u r r e n t T h r e a d ( ). g e t S t a t e ( ) ) ;

Interrupciones Una interrupción es una indicación para que el thread deje de hacer lo que está haciendo para hacer otra cosa. No es aconsejable usar interrupciones! Normalmente los threads reaccionan acabando su ejecución, retornando del método run().

Interrupciones Algunos métodos elevan una InterruptedException si se interrumpe el thread mientras que ejecutan (p. ej. sleep()). Otros métodos bloqueantes no levantan la excepción. Se puede comprobar si el thread ha sido interrumpido invocando Thread.interrupted() si no se invocan métodos que eleven una InterruptedException. Ojo! Thread.interrupted() comprueba si ha sido interrumpido pero limpia el estado de interrupción si devuelve true.

Código p u b l i c v o i d run ( ) {... t r y {... Thread. s l e e p ( 1 0 0 0 ) ;... catch ( I n t e r r u p t e d E x c e p t i o n e ) { // E l t h r e a d ha s i d o i n t e r r u m p i d o m i e n t r a s dormia // y no ha dormido e l tiempo deseado. Retornamos // de run ( ) System. e r r. p r i n t l n ( Thread + Thread. c u r r e n t T h r e a d ( ). g e t I d ( ) + i n t e r r u p t e d, e x i t i n g. ) ; r e t u r n ;...

Código t r y {... / S i e l t h r e a d ha s i d o i n t e r r u m p i d o p e r o no ha s a l t a d o l a e x c e p c i o n, dejamos que l o maneje e l c a t c h l e v a n t a n d o n o s o t r o s mismos l a e x c e p c i o n! i n t e r r u p t e d ( ) l i m p i a e l estado, p e r o e s t e throw l o pondra de nuevo. / i f ( Thread. i n t e r r u p t e d ( ) ) throw new I n t e r r u p t e d E x c e p t i o n ( ) ;... catch ( I n t e r r u p t e d E x c e p t i o n e ) {...

Join Se puede esperar a que un thread muera con join(). Se le puede pasar un tiempo de espera. Thread t = new Thread ( new Worker ( ) ) ; t. s t a r t ( ) ;... t. j o i n ( ) ;

Sincronización Si dos threads acceden al mismo recurso compartido sin estar sincronizados, tendremos una condición de carrera. Java proporciona dos mecanismos básicos de sincronización: Métodos synchronized. Sentencias synchronized.

Métodos synchronized Es un monitor. No es posible que dos invocaciones a métodos synchronized del mismo objeto sean concurrentes. Si un thread está ejecutando un método synchronized, cualquier otro thread que intente invocar un método synchronized de ese objeto se queda bloqueado hasta que pueda proceder. Los constructores no pueden ser synchronized (no tiene sentido).

Métodos synchronized Internamente está implementado mediante un lock (intrinsic lock o monitor lock). Toda instancia tiene asociada un monitor lock. Las clases también tienen su propio lock para sincronizar el acceso a los miembros de clase (métodos estáticos synchronized, etc.). Un thread que necesite acceso exclusivo a la instancia necesita adquirir el lock y después de acceder necesita soltar el lock. Al invocar un método synchronized se adquiere el lock automáticamente y se suelta al finalizar la invocación (por un return o por una excepción). Es un lock re-entrante: desde un método synchronized se puede invocar a otro método synchronized.

Código p u b l i c c l a s s Counter{ p r i v a t e i n t c ; p u b l i c s y n c h r o n i z e d i n t i n c r ( ) { r e t u r n ++c ; public c l a s s Tweeter implements Runnable { p r i v a t e Counter counter ; p u b l i c Tweeter ( Counter c ){ c o u n t e r = c ; @ O v e r r i d e p u b l i c v o i d run ( ) { f o r ( i n t i = 0 ; i < 1 0 ; i ++){ System. out. p r i n t l n ( Thread + Thread. c u r r e n t T h r e a d ( ). g e t I d ( ) + s a y s t w e e e e e t # + c o u n t e r. i n c r ( ) +!!! ) ;

Sentencias synchronized Se debe especificar el objeto del que se quiere adquirir el lock. Un método synchronized es lo mismo que poner synchronized(this) alrededor de todo el método. p u b l i c v o i d i n c r C o u n t e r ( S t r i n g name ) { s y n c h r o n i z e d ( t h i s ) { count++;

wait() wait() bloquea el thread, saliendo del monitor. Siempre se debe comprobar la condición antes de continuar! // d e n t r o de un metodo s y n c h r o n i z e d de l a c l a s e S e r v : // un t h r e a d e s p e r a a que l l e g u e un c l i e n t e w h i l e ( n c l i e n t s == 0) { t r y { w a i t ( ) ; catch ( I n t e r r u p t e d E x c e p t i o n e ) {...

notify() notify() despierta a un thread (cualquiera) de los que están bloqueados en un wait, que competirá por coger el lock del monitor. notifyall() despierta a todos. Sólo debe invocarse desde dentro del monitor. // d e n t r o de o t r o metodo s y n c h r o n i z e d de l a c l a s e S e r v : // l l e g a un c l i e n t e y s e d e s p i e r t a a un t h r e a d // para que l o a t i e n d a a d d C l i e n t ( c ) ; n c l i e n t s ++; n o t i f y A l l ( ) ;

Volatile Las variables volatile se leen/escriben de forma atómica. La escritura de una variable volatile fuerza una relación pasa-antes-que: si un thread ve la variable modificada, ve el estado generado por cualquier acción previa del thread que la modificó. Ojo: esto no nos protege de la mayoría de las condiciones de carrera. p u b l i c c l a s s Counter { p r i v a t e v o l a t i l e l o n g count = 0 ; p u b l i c v o i d i n c r e m e n t ( ) { count++; // CONDICION DE CARRERA!!!

Executor El paquete java.util.concurrent ofrece la interfaz Executor: Es una interfaz para lanzar nuevas tareas y evitar el idiom para crear un thread. Sólo tiene un método, execute(). Los detalles de la ejecución dependen de la implementación concreta de la interfaz (ejecución inmediata, esperar un worker, etc.). No hay forma de obtener el resultado de la tarea. Estas dos sentencias pueden ser equivalentes: ( new Thread ( r ) ). s t a r t ( ) ; e. e x e c u t e ( r ) ;

ExecutorService Extiende la interfaz Executor con submit() que permite pasar objetos que implementen Runnable. Retorna un objeto Future que sirve para consultar y controlar el progreso de la tarea. shutdown() impide ejecutar nuevas tareas, pero deja que las que están en marcha puedan acabar. shutdownnow() acaba las tareas en marcha y retorna una lista de tareas que estaban esperando para ejecutar. No da garantías sobre lo que pasará (si terminarán, se pararán, etc.). awaittermination() se bloquea hasta que termine el proceso de shutdown o salte el timeout. La clase Executors proporciona factory methods para los distintos ExecutorServices.

ExecutorService E x e c u t o r S e r v i c e p o o l = E x e c u t o r s. newfixedthreadpool ( 1 0 ) ;... p o o l. e x e c u t e ( new C l i e n t M g r ( ) ) ;... p o o l. shutdown ( ) ; i f (! p o o l. a w a i t T e r m i n a t i o n ( 6 0, TimeUnit. SECONDS) ) { p o o l. shutdownnow ( ) ; i f (! p o o l. a w a i t T e r m i n a t i o n ( 6 0, TimeUnit. SECONDS) ) System. e r r. p r i n t l n ( Pool d i d not t e r m i n a t e ) ;

Futures El método submit() permite pasar al executor una clase que implemente Runnable. Retorna un objeto Future que sirve para consultar y controlar el progreso de la tarea. El método get() del Future se bloquea y retorna null cuando la tarea ha terminado.

ExecutorService E x e c u t o r S e r v i c e p o o l = E x e c u t o r s. newfixedthreadpool ( 1 0 ) ; Future <?> f u t u r e = p o o l. submit ( new Runnable ( ) { p u b l i c v o i d run ( ) { t r y { Thread. s l e e p ( 2 0 0 0 ) ; catch ( I n t e r r u p t e d E x c e p t i o n e ) { e. p r i n t S t a c k T r a c e ( ) ; ) ; i f ( f u t u r e. g e t ( ) == n u l l ) System. out. p r i n t l n ( Termino ok ) ;

ExecutorService El método submit() también permite pasar objetos que implementen Callable. Un objeto Callable debe implementar un método call() que retorna un valor. El valor retornado por call() se obtiene con el método get() del objeto Future.

ExecutorService E x e c u t o r S e r v i c e p o o l = E x e c u t o r s. newfixedthreadpool ( 1 0 ) ; Future <S t r i n g > f u t u r e = p o o l. submit ( new C a l l a b l e <S t r i n g >(){ p u b l i c S t r i n g c a l l ( ) throws E x c e p t i o n { System. out. p r i n t l n ( Hola!! ) ; r e t u r n He t e r m i n a d o b i e n!! ; ) ; System. out. p r i n t l n ( Cadena de s a l i d a de l a t a r e a : + f u t u r e. g e t ( ) ) ;

Colecciones concurrentes El paquete java.util.concurrent proporciona clases con estas interfaces: BlockingQueue: FIFOs bloqueantes, ya las conocemos. ConcurrentMap: Diccionarios (nombre-valor) con operaciones atómicas.

BlockingQueue Es una cola para comunicar procesos. Ampĺıa la interfaz Queue con operaciones bloqueantes.

BlockingQueue p u b l i c i n t e r f a c e BlockingQueue<E> extends Queue<E> { boolean put (E e ) ; // como add, p e r o b l o q u e a E t a k e ( ) ; // como e l e m e n t ( ), p e r o b l o q u e a

BlockingQueue Bloqueantes sin timeout: put(e): inserta un elemento. take(): elimina la cabeza y la devuelve. Bloqueantes con timeout: offer(e, time, unit): inserta un elemento. poll(time, unit): elimina la cabeza y la devuelve.

Thread-safeness Podemos crear una colección envuelta con decorators para hacerla thread-safe. Para ello podemos usar los métodos de Collections synchronizedset o synchronizedmap p u b l i c s t a t i c <T> Set<T> s y n c h r o n i z e d S e t ( Set<T> s ) ; Por ejemplo: Set s = C o l l e c t i o n s. s y n c h r o n i z e d S e t ( new HashSet ( ) ) ;