Tema III. Multihilo Desarrollo de Aplicaciones para Internet Curso 12 13
Índice 1.Introducción 2.Tipos de Concurrencia 3.Hilos en Java 4.Implementación de un SNB i. Sin Hilos ii. Con Hilos iii.con Pool de Hilos 5.Referencias
Índice 1.Introducción 2.Tipos de Concurrencia 3.Hilos en Java 4.Implementación de un SNB i. Sin Hilos ii. Con Hilos iii.con Pool de Hilos 5.Referencias
Introducción La naturaleza cliente(s)/servidor de las aplicaciones hace que necesario el uso de concurrencia El tiempo de respuesta es muy importante Usos habituales Servidores no bloqueantes (SNB) El procesado de una petición no debe esperar a que se responda a las peticiones previas Es necesario procesar las peticiones en paralelo Manejo de peticiones asíncronas Se evita el bloqueo de la aplicación que espera la respuesta a una petición remota
Índice 1.Introducción 2.Tipos de Concurrencia 3.Hilos en Java 4.Implementación de un SNB i. Sin Hilos ii. Con Hilos iii.con Pool de Hilos 5.Referencias
Tipos de concurrencia Basada en procesos Proceso: Instancia de un programa en ejecución, incluyendo los valores actuales del contador de programa, registros y variables La concurrencia se consigue creando copias de procesos (programas) Creación más lenta Espacio de memoria propio Necesita más memoria Programación más sencilla Basada en hilos (threads) Hilo: Flujo de ejecución dentro de un proceso. Es la menor unidad de procesamiento de un S.O. La concurrencia se consigue creando varios flujos de ejecución dentro de un mismo proceso (programa) Creación más rápida (10-100 veces) Espacio de memoria compartido: Menos memoria Programación más complicada Más habitual El uso de hilos en aplicaciones para Internet suele ser para desarrollar acciones independientes, por lo que no es necesaria la sincronización de los mismos
Manejo de Memoria Procesos Memoria Compartida [Opcional] Hilos Memoria del Proceso Memoria Proceso Asignada Memoria del Proceso Memoria del Proceso Proceso... Proceso Hilo... Hilo
Ciclo de Vida de un Hilo Listo En ejecución Bloqueado Finalizado
Índice 1.Introducción 2.Tipos de Concurrencia 3.Hilos en Java 4.Implementación de un SNB i. Sin Hilos ii. Con Hilos iii.con Pool de Hilos 5.Referencias
Threads en Java La clase java.lang.thread representa un hilo en Java Su ejecución debe iniciarse explícitamente mediante el método start Su comportamiento puede proporcionarse mediante clases que implementen la interfaz java.lang.runnable
Ciclo de Vida de un Thread Creado start Completar E/S despachar Listo Fin intervalo sueño wait notify notifyall Ejecución desalojar resume* Solicitud E/S sleep suspend* Vivo (Alive) Espera Bloqueado Dormido Suspendido stop* Fin Ejecución * Métodos obsoletos (evitar su uso) Muerto
Arquitectura de Memoria en Java Memoria compartida Memoria no compartida * Imagen tomada de: http://blog.codecentric.de/en/2010/01/the-java-memory-architecture-1-act/
Índice 1.Introducción 2.Tipos de Concurrencia 3.Hilos en Java 4.Implementación de un SNB i. Sin Hilos ii. Con Hilos iii.con Pool de Hilos 5.Referencias
Implementación de un SNB Vamos a ver como implementar un servidor no bloqueante en Java: Las peticiones deben procesarse en paralelo, de modo que un cliente no tenga que esperar a que finalicen las peticiones anteriores antes de que se procese la suya Partiremos del ejemplo EchoServer del tema anterior al que añadimos las clases IOManager y SocketIOManager para gestión de E/S
IOManager y SocketIOManager
EchoClient
EchoServer
EchoServer Problemas Solo se puede dar servicio a un cliente El resto de clientes deben esperar a que se dé servicio al cliente activo
Índice 1.Introducción 2.Tipos de Concurrencia 3.Hilos en Java 4.Implementación de un SNB i. Sin Hilos ii. Con Hilos iii.con Pool de Hilos 5.Referencias
EchoServer No Bloqueante Sin Hilos Evitando los bloqueos en los métodos bloqueantes podemos conseguir un SNB accept: Utilizando setsotimeout podemos limitar el tiempo de bloqueo readline: Invocando el método canread del SocketIOManager podemos saber si hay algo que leer en el flujo Solo es necesario un hilo para gestionar el servidor
EchoServer No Bloqueante Sin Hilos
EchoServer No Bloqueante Sin Hilos Al utilizar setsotimeout hacemos que el bloqueo de accept dure un máximo de 1000 ms
EchoServer No Bloqueante Sin Hilos
Ventajas EchoServer No Bloqueante Sin Hilos Se atiende a varios clientes simultáneamente Problemas Se desperdicia tiempo esperando peticiones Se desperdicia CPU al tener que estar comprobando continuamente si hay nuevos clientes o hay algo que leer
Índice 1.Introducción 2.Tipos de Concurrencia 3.Hilos en Java 4.Implementación de un SNB i. Sin Hilos ii.con Hilos iii.con Pool de Hilos 5.Referencias
EchoServer No Bloqueante Con Hilos Mediante el uso de hilos podemos evitar desperdiciar recursos en un SNB Existen dos tipos de hilo en el servidor Hilo Servidor: Un único hilo será el responsable de aceptar las conexiones de los clientes Hilos de Servicio: Cada cliente será atendido por uno o varios hilos de servicio
EchoServer No Bloqueante Con Hilos 1.El cliente solicita la conexión con el hilo servidor 2.El hilo servidor crea un hilo de servicio que atenderá al cliente 3.El cliente se comunica directamente con el hilo de servicio
EchoServer No Bloqueante Con Hilos Hilo Servidor
EchoServer No Bloqueante Con Hilos Hilo Servidor (Main)
Ventajas EchoServer No Bloqueante Con Hilos Se atiende a varios clientes simultáneamente No hay desperdicio de tiempo, puesto que el hilo principal se bloquea a la espera de peticiones mientras que los hilos ServerThread dan servicio a los clientes Problemas Puede haber problemas de rendimiento ante un alto número de conexiones
Índice 1.Introducción 2.Tipos de Concurrencia 3.Hilos en Java 4.Implementación de un SNB i. Sin Hilos ii. Con Hilos iii.con Pool de Hilos 5.Referencias
Ejecutores en Java Manejan la ejecución de un grupo de Thread Java proporciona una serie de clases en el paquete java.util.concurrent Interfaces principales Executor: Interfaz común que define un método para ejecutar Runnable ExecutorService: Añade a Executor métodos que generan objetos Future para seguir el progreso de una o más tareas asíncronas ScheduledExecutorService: Añade a ExecutorService métodos para ejecutar tareas con un determinado retraso o de forma periódica
Patrón Thread Pool
java.util.concurrent.threadpoolexecutor Implementación de la interfaz ExecutorService Mantiene un pool de Thread con los que ejecuta las tareas recibidas Si cuando se recibe una tarea hay algún Thread libre, se le asigna la tarea y se ejecuta Si no, la tarea se guarda en una cola hasta que haya un Thread libre Suele crearse a través de los métodos estáticos de la clase Executors: newfixedthreadpool y newcachedthreadpool
EchoServer No Bloqueante Thread Pool
Ventajas EchoServer No Bloqueante Thread Pool Permite controlar el número máximo de hilos creados por el sistema Evita la sobrecarga del servidor
Índice 1.Introducción 2.Tipos de Concurrencia 3.Hilos en Java 4.Implementación de un SNB i. Sin Hilos ii. Con Hilos iii.con Pool de Hilos 5.Referencias
Referencias Schmint, D., Stal, M., Rohnert, H., Buschmann. Pattern-Oriented Software Architecture Volume 2: Patterns for Concurrent and Networked Objects. John Willey & Sons (2000) Patterns for Concurrent, Parallel and Distributed Systems [ http://www.cs.wustl.edu/~schmidt/patterns-ace.html - Última Visita 07/09/2012]