CONCEPTES AVANATS DE SISTEMES OPERATIUS Departament dArquitectura de

  • Slides: 28
Download presentation
CONCEPTES AVANÇATS DE SISTEMES OPERATIUS Departament d’Arquitectura de Computadors Sincronización de Threads en Java

CONCEPTES AVANÇATS DE SISTEMES OPERATIUS Departament d’Arquitectura de Computadors Sincronización de Threads en Java (Seminaris de CASO) Autors Josep Joan Ribas Prats o Sergio Liminiana Bernat o

Introducción Los threads o hilos de ejecución son segmentos de código de un programa

Introducción Los threads o hilos de ejecución son segmentos de código de un programa que se ejecutan secuencialmente de modo independiente de otras partes del programa. o Un proceso puede estar constituido por uno o mas threads. o Un thread esta compuesto por : o – Una CPU virtual – El código que ejecuta el procesador – Los datos sobre los que trabaja el código o Dos threads comparten código si ejecutan código de objetos que pertenecen a la misma clase. 2

Introducción (II) o Los datos pueden ser o no compartidos por diferentes threads. Eso

Introducción (II) o Los datos pueden ser o no compartidos por diferentes threads. Eso ocurre cuando tienen acceso a un objeto común. 3

Para qué? o Los threads se utilizan para aislar y coordinar tareas. o Sin

Para qué? o Los threads se utilizan para aislar y coordinar tareas. o Sin el uso de threads hay aplicaciones que son casi imposibles de programar: • Las que tienen tiempos de espera importantes entre etapas • Las que consumen muchos recursos de CPU e impiden que el procesador atienda simultáneamente otros eventos o peticiones del usuario 4

Tipos. o Tipos de threads que pueden aparecer en una aplicación: • Threads completamente

Tipos. o Tipos de threads que pueden aparecer en una aplicación: • Threads completamente independientes, que realizan tareas no relacionadas. Éste es el caso más sencillo y no requiere ninguna programación especial. • Threads que trabajan en una misma tarea, pero sin interferir ni intercambiar relación entre ellos. Por ejemplo, threads que colaboran en el producto de dos matrices ocupándose cada una de ellas de calcular ciertas filas de la matriz producto. 5

Tipos(II). • Threads que utilizan recursos de modo mutuamente exclusivo, aunque sin tener que

Tipos(II). • Threads que utilizan recursos de modo mutuamente exclusivo, aunque sin tener que coordinar sus actividades. Por ejemplo, threads que actualizan o leen registros de una base de datos y que no pueden actuar simultáneamente. • Threads que deben de coordinar sus actividades, de modo que una de ellas no puede empezar o continuar hasta que la otra haya realizado su tarea. Los ejemplos más típicos son los de tipo productor-consumidor, en el que este último tiene que esperar para realizar su función a que el productor le haya preparado los datos y le avise de esa circunstancia. 6

Creación. o Hay dos modos de conseguir threads en Java. Una es extender la

Creación. o Hay dos modos de conseguir threads en Java. Una es extender la clase Thread, la otra es implementando la interface Runnable. 7

Creación extendiendo la clase Thread o El nuevo thread se crea extendiendo la clase

Creación extendiendo la clase Thread o El nuevo thread se crea extendiendo la clase Thread y redefiniendo el metodo run(). o Exemple: public class My. Thread extends Thread{ public void run(){ // código propio del thread } } public static void main(){ Thread t= new My. Thread(); t. start; } 8

Creación implementando la interface Runnable o El constructor de la clase Thread recibe un

Creación implementando la interface Runnable o El constructor de la clase Thread recibe un argumento que debe ser una instancia de una clase que implementa la interface Runnable, implementando el metodo run(). 9

Creación implementando la interface Runnable(II) o Ejemplo: public class Thread. Test{ public static void

Creación implementando la interface Runnable(II) o Ejemplo: public class Thread. Test{ public static void main(String args[]{ Xyz r = new XYZ(); Thread t = new Thread( r ); } } class Xyz implements Runnable { int i; public void run(){ while (true){ System. out. println(“Hello” + i++); if (i==50) break; } } } 10

Qué mecanismo usar? o Implementar la interfaz Runnable: • Mejor diseño orientado a objetos.

Qué mecanismo usar? o Implementar la interfaz Runnable: • Mejor diseño orientado a objetos. La clase thread solo deberá ser extendida cuando se pretenda modificar o extender el comportamiento de dicho modelo de ejecución. • Herencia simple. Debido a la tecnología de Java no es posible extender una clase cuando ésta ya ha sido extendida a la clase thread o Extender la clase Thread: • Código más simple. En el método run la referencia this apunta a la instancia del thread actual 11

Estados de un thread. Otherwise Blocked sleep() timeout thread join() interrupt() New start() sleep()

Estados de un thread. Otherwise Blocked sleep() timeout thread join() interrupt() New start() sleep() join() Runnable Running wait() Blocked in objects wait() pool run() Dead synchronized() lock available Blocked in objects lock pool notify() interrupt() 12

Estados de un thread (II). · Nuevo (New): El thread ha sido creado pero

Estados de un thread (II). · Nuevo (New): El thread ha sido creado pero no inicializado (no se ha ejecutado todavía el método start()), por lo que todavía no puede ejecutarse. · Ejecutable (Runnable): El thread puede estar ejecutándose, siempre y cuando se le asigne tiempo de CPU. (Scheduler) 13

Estados de un thread (III). · Muerto (Dead): La forma habitual de morir en

Estados de un thread (III). · Muerto (Dead): La forma habitual de morir en un thread es finalizando de ejecutar el método run(), bien por terminar su tarea, bien dejando de cumplir una condición chequeada en dicho método. · Bloqueado (Blocked o Not Runnable): El thread podría estar ejecutándose, pero hay algo que lo impide, como por ejemplo una operación de E/S. Mientras un thread esté en este estado, no se le asigna tiempo de CPU. 14

Planificación de threads. o La planificación de ejecución de threads se basa en el

Planificación de threads. o La planificación de ejecución de threads se basa en el modelo de prioridades y no utiliza el modelo de segmentación por segmentos de tiempo. o Un thread continuará ejecutandose en la CPU hasta pasar a un estado que no le permita seguir en ejecución. Se debe asegurar que el thread permite la ejecución de otros threads, esto se puede conseguir mediante llamadas al método sleep(). 15

Planificación de threads(II). o Ejemplo: public class Xyz implements Runnable { public void run()

Planificación de threads(II). o Ejemplo: public class Xyz implements Runnable { public void run() { While(true){ // código del propio thread try{ // permitimos la ejecución de otros threads Thread. sleep(10); } catch(Interrupted. Exception e) { // otro thread despierta a este thread } } } – Los threads pueden invocar al método interrupt() de otros threads para reanimarlos. 16

Planificación de Threads(III). o Otro método para permitir la ejecución de otros threads es

Planificación de Threads(III). o Otro método para permitir la ejecución de otros threads es el método yield() que permite la ejecución de otro thread con la misma prioridad. o Las prioridades viene definidas por variables miembro de la clase Thread, que toman valores int entre unos valores MAX_PRIORITY y MIN_PRIORITY (entre 1 y 10), siendo la prioridad por defecto NORM_PRIORITY(5). 17

Planificación de Threads(IV). Cuando se crea un thread, hereda la prioridad del thread que

Planificación de Threads(IV). Cuando se crea un thread, hereda la prioridad del thread que la ha creado. o Para modificar la prioridad de un thread se utiliza el método set. Priority(int), y para obtener su valor el método int get. Priority(). o El algoritmo de distribución de recursos en Java: o • Es preemptive, es decir, el sistema ejecuta el thread de mayor prioridad entre todos los que son Runnable (excepcionalmente puede ejecutarse otro thread para evitar que algunos procesos “duerman” indefinidamente). • Si varios threads en estado Runnable tienen la misma prioridad se van ejecutando sucesivamente mediante permutación cíclica 18

Planificación de Threads(V). o Threads Daemon – Los threads daemon llamodos servicios, se ejecutan

Planificación de Threads(V). o Threads Daemon – Los threads daemon llamodos servicios, se ejecutan con prioridad baja y proporcionan un servicio básico a un programa o programas cuando la actividad de la máquina es reducida. – Un ejemplo de thread demonio que está ejecutándose continuamente es el recolector de basura (garbage collector). E – Un thread puede fijar su indicador de demonio pasando un valor true al método set. Daemon(). Si se pasa false a este método, el thread será devuelto por el sistema como un thread de usuario. No obstante, esto último debe realizarse antes de que se arranque 19 el thread (start()).

Control básico de threads. o Finalización del la ejecución de un thread. – Cuando

Control básico de threads. o Finalización del la ejecución de un thread. – Cuando un thread acaba su ejecución y es finalizado , no puede volver a ser ejecutado. – Podemos detener un thread utilizando un flag que utiliza un metodo run que debe terminar la ejecución. • r. stop. Running() // r instancia de una clase que implementa runnable 20

Control básico de threads (II). o Verificación del estado thread is. Alived() • boolean

Control básico de threads (II). o Verificación del estado thread is. Alived() • boolean is. Alived(). Devuelve true si el thread ha sido inicializado con start y no ha terminado el ciclo de ejecución. o Bloqueo de threads. • sleep(). Permite detener un thread durante un determinado tiempo • join(). Bloquea el thread actual, hasta que el thead sobre el cual ha sido ejecutado el join termina. 21

Sincronización. o Existen muchas situaciones interesantes donde ejecutar threads concurrentes que compartan datos y

Sincronización. o Existen muchas situaciones interesantes donde ejecutar threads concurrentes que compartan datos y deban considerar el estado y actividad de otros threads. Este conjunto de situaciones de programación son conocidos como escenarios 'productor/consumidor'; donde el productor genera un canal de datos que es consumido por el consumidor. Como los threads comparten un recurso común, deben sincronizarse de alguna forma. 22

Sincronización. Uso de synchronized o Cada objeto tiene un “flag de bloqueo” – La

Sincronización. Uso de synchronized o Cada objeto tiene un “flag de bloqueo” – La palabra clave synchronized permite controlar el flag para activar accesos exclusivos al objeto y cada objeto tendrá asociada una cola de espera. • Se pueden declarar bloques de código synchronized ( variable. Compartida ) { // acceso al recurso } 1. Métodos synchronized public synchronized void nom. Metode () { // acceso al recurso } 23

Sincronización. Uso de synchronized o El flag de bloqueo de un objeto se libera

Sincronización. Uso de synchronized o El flag de bloqueo de un objeto se libera : – Cuando el thread termina el bloque de código synchronized – Cuando le bloque de código synchronized lanza una excepción. o Deadlock – Dos threads esperando un flag de bloqueo – No se detecta – Se puede evitar: • Decidir el orden de obtención de los bloqueos • Seguir con rigurosidad ese orden • Liberar los bloqueos en orden inverso 24

Sincronización. Comunicación entre threads o wait() y notify() – Si un thread ejecuta una

Sincronización. Comunicación entre threads o wait() y notify() – Si un thread ejecuta una llamada wait() sobre un objeto x pausará su ejecución hasta que otro thread ejecute la llamada a notify() mediante el mismo objeto x. – Para poder ejecutar tanto un wait() como un notify() el thread debera disponer del flag de bloqueo, es decir, solo podrán ser ejecutadis desde un bloque de codigo synchronized. – Listas de espera o “pools” • Cuando un thread ejecuta wait() se libera el flag de bloqueo y es colocado en la lista de espera o pool del objeto (wait pool) • Al ejecutar notify() un thread abitrario es movido de la lista de espera hacia una lista de threads que esperan por el flag de bloqueo (lock pool). notify. All() despierta a todos los threads. 25

Sincronización. Monitores o Cuando un método synchronized se ejecuta adquiere un monitor sobre el

Sincronización. Monitores o Cuando un método synchronized se ejecuta adquiere un monitor sobre el objeto. Cuando un thread tiene el monitor del objeto ningún otro thread podrá ejecutar un metodo synchronized. o Un thread sale del monitor cuando libera el flag de bloqueo del objeto. 26

Sincronización. Monitores(II). o o Un ejemplo típico del uso de monitores es el esquema

Sincronización. Monitores(II). o o Un ejemplo típico del uso de monitores es el esquema de pro Aquí el productor y el consumidor son threads que acceden a 27

Bibliografia Dossier Programación Java (Tomo 2) PUE o http: //server 2. ok. cl/java/Cap 7/thread.

Bibliografia Dossier Programación Java (Tomo 2) PUE o http: //server 2. ok. cl/java/Cap 7/thread. html o http: //www. medicina. ull. es/aula/tutoriales/java/mo nitors. html o 28