SlideShare una empresa de Scribd logo
1 de 25
Descargar para leer sin conexión
Programación Concurrente en Java




                       Curso 2006-2007




            9/2/2007           Prog. Distribuida Bajo Internet
¿Qué es la Programación Concurrente?

       Diseño basado en varias actividades independientes
        –   Conceptualmente se ejecutan en paralelo
                En un nodo, multiplexa el tiempo de procesador entre las
                 tareas
                En un sistema distribuido, paralelismo real
       Las actividades deben cooperar entre sí
        –   Comunicación
        –   Sincronización
       Actividades = procesos o threads (hilos)


2                              09/02/2007              Prog. Distribuida bajo Internet
Utilidad de la programación
    concurrente

       Mejora las características de:
        –   Flexibilidad
        –   Interactividad
        –   Eficiencia
       Facilita el diseño de sistemas
        –   Reactivos (responden a estímulos externos)
        –   Con actividades lógicamente separadas y distintos niveles
            de prioridad
        –   Con actividades periódicas
        –   Ej.- atención a varios clientes, timeouts, etc.

3                            09/02/2007           Prog. Distribuida bajo Internet
Dificultades a resolver
       Puede darse cualquier intercalado de
        ejecución
       Los programas deben ser correctos bajo
        cualquier intercalado posible
        –   Ejemplo.- acceso a cuenta bancaria
       Posibles interferencias entre tareas
        –   Resultado incorrecto bajo ciertos intercalados (no
            determinismo)
       Vivacidad, interbloqueos
4                         09/02/2007        Prog. Distribuida bajo Internet
Proceso
       Abstracción proporcionada por el SO (ej Unix)
        –   El SO planifica y ejecuta varios procesos
                Algoritmo de planificación
                   –   Cooperativo (cada proceso se autolimita)
                   –   Expulsivo (el sistema limita el tiempo dedicado a cada proceso)
        –   Cada proceso mantiene su propio estado
                Pila
                Áreas de datos
                Ficheros abiertos, etc.
        –   Existe una jerarquía de objetos (relación padre-hijo)
                Padre e hijo comparten información
                   –   Ficheros abiertos
                   –   Pipes y streams
                   –   Sockets
                Pueden comunicarse/sincronizarse


5                                   09/02/2007                     Prog. Distribuida bajo Internet
Thread (Thread=hilo=proceso ligero)

       Hilos = Actividades concurrentes dentro de un proceso
       Comparten el contexto del proceso padre
         –   Variables compartidas
         –   Ficheros abiertos, etc.
       Pero cada hilo mantiene una parte local
         –   Pila local
         –   Variables locales, etc
       Creación/destrucción/comunicación/cambio estado mucho más
        eficiente que con procesos
       La memoria compartida facilita la comunicación y sincronización
         –   Pero aparecen posibles interferencias
       Nos centramos en hilos (Threads)
         –   Asumimos acceso a variables comunes



6                                 09/02/2007          Prog. Distribuida bajo Internet
Interferencias
       Muchas operaciones suponen tanto lecturas como escrituras
         –   Ej.- i++ consiste a bajo nivel en varias operaciones primitivas
                  r<-[i], inc r, [i]<-r
       Esas operaciones no se tratan como atómicas
         –   El planificador puede interrumpirla en cualquier punto, cediendo el control a otro hilo
         –   Puede darse cualquier intercalado de ejecución
       Ej dos hilos A, B ejecutan concurrentemente sendas instrucciones i++
         –   A ejecuta r<-[i]
         –   B ejecuta i++ (todos los pasos)
         –   A ejecuta inc r, [i]<-r
         –   Hemos perdido el cambio introducido por B
       Solución
         –   Concepto de sección crítica (exlusión mútua)
         –   Sincronización (reservas, semáforos, monitores, etc.)




7                                          09/02/2007                 Prog. Distribuida bajo Internet
¿Porqué Java?
       Incorpora construcciones para Programación Concurrente
        –   Los hilos forman parte del modelo del lenguaje
                Aplicación = hilos usuario + hilos sistema (ej.- para GC y GUI)
                Hilos usuario.- uno para el método main(), y podemos crear otros
                La aplicación termina cuando finalizan todos sus hilos usuario
        –   Facilita el desarrollo de aplicaciones concurrentes
       Lenguaje conocido (Prog. Avanzada)
       Demandado por el mercado
       Además
        –   Facilidades para programación en red
                Plataforma de distribución de bajo nivel
        –   Facilidades para Objetos Distribuidos
                Plataforma de distribución de nivel intermedio


8                                 09/02/2007                 Prog. Distribuida bajo Internet
Prog. Concurrente en Java
       Creación de hilos
       Ej.- Servidor multi-hilo
       Ciclo de vida de los hilos
       Estados de un hilo vivo
       Sincronización
        –   Exclusión mútua
        –   Espera y notificación
       Ejemplo
       Interbloqueos
9                            09/02/2007   Prog. Distribuida bajo Internet
Creación de hilos
        Crear nueva clase como extensión de Thread
          class X extends Thread {
              …
              public void run() {..} // codigo del hilo
          }
          … X h= new X(); h.start();
        Implementar interface Runnable
          class X implements Runnable {
              Public void run() {..} // codigo del hilo
          }
          .. Thread h= new Thread(new X()); h.start();
        La actividad se inicia al aplicar el método start sobre el objeto
         hilo


10                                09/02/2007              Prog. Distribuida bajo Internet
Creación de hilos.- ej

        import java.io.*;
        public class T extends Thread {
               protected int n;
               Public static void main(String[] argv) {
                      for (int i = 0; i<3; i++) new T(i).start();
               }
               public T(int n) {this.n = n;}
               public void run() {
                      int i = 0;
                      while (count < 5) {
                               System.out.println(“Hilo " + n + " iteracion " + i++);
                               try {sleep((n + 1) * 1000);}
                               catch(InterruptedException e) {e.printStackTrace();}
                      }
                      System.out.println(“El hilo " + n + " ha terminado");
               }
        }

11                                     09/02/2007                              Prog. Distribuida bajo Internet
Estructura de un servidor

        Servidor secuencial
         while (msg = getMessage())
            Gestiona el mensaje
        Servidor concurrente
         while (msg = getMessage())
            Crea nueva tarea para gestionar el mensaje
        El servidor concurrente puede atender varios
         clientes simultáneamente

12                        09/02/2007           Prog. Distribuida bajo Internet
Ciclo de vida de los hilos


       new()                start()
               Creado                 Vivo

                Stop()                Stop(), end()


                         Finalizado



13                       09/02/2007           Prog. Distribuida bajo Internet
Estados de un hilo vivo

                                            start()
                           dispatch
                                                      Stop()
           Preparado                  Ejecución
                            yield()

                       resume()                                    end
          suspend()                    sleep(), suspend()
                        Espera




14                    09/02/2007              Prog. Distribuida bajo Internet
Estados de un hilo vivo
        start
          –     inicia la ejecución de ‘run’
        isAlive
          –     cierto si tarea iniciada y no finalizada
        stop
          –     Finaliza la tarea
        suspend
          –     Suspende temporalmente la tarea (hasta ‘resume’)
        sleep
          –     Suspende la tarea un periodo especificado (en milisegundos)
        join
          –     Suspende hasta que finaliza otra tarea
        interrupt
          –     Aborta la espera iniciada con ‘sleep’, ‘wait’ o ‘join


15                                     09/02/2007                       Prog. Distribuida bajo Internet
Ejemplo de interferencias
        Suponemos un conjunto de cuentas bancarias
        Varios hilos utilizan esas cuentas
         –   Cada hilo usa dos cuentas, transfiriendo n unidades de la
             primera a la segunda
         –   La selección de la cuenta destino y la cantidad son
             aleatorias
         –   Cada hilo cede el control (yield) en mitad de una
             transferencia
                 Simula una posible expulsión por parte del SO
                 Con ello aumentamos la probabilidad de interferencias
        La suma total (valor acumulado de todas las
         cuentas) debe ser constante

16                              09/02/2007              Prog. Distribuida bajo Internet
Ejemplo de interferencias
     import java.io.*;
     public class Interferencias {                                          class Banco {
              public static void main(String[] args) {                              private int[] cuenta;
                        Banco b = new Banco(10, 1000);                              private long ntransf = 0;
                        for (int i =0; i <numCuentas; i++)                          public int size() {return cuenta.length; }
                                   (new Transf(b, i, sadoInicial)).start();         public Banco(int n, int v0) {
              }                                                                               cuenta = new int[n]; ntransf = 0;
            }                                                                                 for (int i = 0; i < size(); i++) cuenta[i] =
                                                                                         v0;
     class Transf extends Thread {                                                  }
              private Banco banco; private int from, max;                           public void transfiere(int from, int to, int n) {
              private int rand(int n) {(int)n*Math.random();}                                 if (cuenta[from] < n) return;
              public Transf (Banco b, int from, int max) {                                    cuenta[from] -= n;
                        banco = b; This.from = from; this.max = max;                          Thread.currentThread().yield();
              }                                                                               cuenta[to] += n; if (++ntransf % 10
              public void run() {                                                        == 0) test();
                        try {                                                       }
                                   while (!interrupted()) {                         public void test() {
                                             banco.transfiere(from,                           int total = 0;
                                     rand(banco.size()), rand(max));                          for (int i = 0; i<size(); i++) total+=
                                             sleep(1);                                   cuenta[i];
                                   }                                                          System.out.println("Transferencias:"+
                                                                                         ntransf +
17            }
                        } catch(InterruptedException e) {}
                                                   09/02/2007                            Prog. Distribuida bajo Internet
                                                                                                   " Total: " + total);
     }                                                                              }
Sincronización y exclusión mútua

        Las tareas deben cooperar entre sí
         –   Comparten objetos
                 Ej. una tarea modifica el estado del objeto, otra lo consulta
         –   Pueden haber interferencias
                 Sólo pueden aparecer en fragmentos de código que acceden
                  a objetos compartidos
                 Solución = garantizar ejecución secuencial de dichos
                  fragmentos de código = exclusión mútua
         –   Palabra reservada ‘synchronized’
                 Puede aplicarse a métodos: synchronized void m() {..}
                 Y a bloques de código: synchronized(objeto) {..}
                 Se interpreta como una sección crítica que impide la ejecución
                  simultánea de otros métodos sincronizados
                 La usamos para todo recurso que requiere acceso atómico

18                               09/02/2007                Prog. Distribuida bajo Internet
Ejemplo revisado
        En el ejemplo anterior teníamos problemas de interferencias en
         el acceso a las cuentas
        Usamos synchronized en las funciones que acceden a las
         cuentas (transferencia y test)
         public synchronized void transferencia(..) ..
         public synchronized void test(..) ..
        Con ello corregimos el problema
        Pero restringimos demasiado la concurrencia
         –   Dos transferencias que trabajan sobre cuentas distintas no pueden
             interferir entre sí, pero las ejecutamos en exclusión mútua
         –   La solución es restringir el acceso únicamente a las dos cuentas
             utilizadas por cada hilo


19                                    09/02/2007         Prog. Distribuida bajo Internet
Espera y notificación

        Método parcial = método que sólo debe activarse en
         determinados estados del objeto
         –   Ej.- extraer de una lista (sólo si no vacía)
        Métodos parciales en objetos compartidos
         –   Si un hilo invoca un método parcial en un estado incorrecto,
             debe esperar
         –   Cuando otro hilo modifica el estado debe notificar el cambio
             a un hipotético hilo en espera (notificación)
        Métodos de sincronización
         –   wait.- suspende hilo, libera exclusión mútua
         –   notify.- reactiva uno de los hilos suspendidos por wait
         –   notifyAll.- idem., pero los reactiva todos
20                            09/02/2007             Prog. Distribuida bajo Internet
Ejemplo de espera y notificación
        Productor consumidor
         –   Una hilo genera valores y los inserta en una cola
         –   Otro hilo extrae valores de la cola y los escribe en pantalla
         –   La cola mantiene orden FIFO (first-in first-out)
        Implementamos la cola como vector circular
         –   Vector de enteros de talla N
                 Permite almacenar hasta N valores generados y todavía no
                  consumidos
         –   Tres variables que representan el índice donde insertar, índice
             donde extraer, y número de elementos (i,e,n)
         –   Operaciones
                 void put(int x)
                 int get()
                 boolean lleno()
                 boolean vacio()
21                                  09/02/2007              Prog. Distribuida bajo Internet
Ejemplo de espera y notificación
     public class prodCons {                                             class Buffer {
       public static void main(char[] args) {                              private int[] v;
         Buffer b= new Buffer(4);                                          private int N, n, i, e;
         (new Productor(b,20)).start();                                    private boolean lleno() {return n==N;}
         (new Consumidor(b)).start();                                      private boolean vacio() {return n==0;}
       }
     }                                                                       public Buffer(int max) {
                                                                               N=max; n=e=i=0; v=new int[N];
     class Productor extends Thread {                                        }
       private int N;                                                        public synchronized void put(int x) {
       public Productor (int max) {N=max;}                                     while (lleno()) wait();
       public void run() {                                                     v[i]=x; i=(i+1)%N; n++;
         for (int i=0; i<N; i++) b.put(i);                                     notifyAll();
         b.put(-1); System.out.println(“Fin del productor”);                 }
       }                                                                     public synchronized int get() {
     }                                                                         while (vacio()) wait();
                                                                               int x=v[e]; e=(e+1)%N; n--;
     class Consumidor extends Thread {                                         notifyAll();
       public void run() {                                                     return x;
         do{ int x=b.get(); System.out.println(“ “+x); } while (x>=0);       }
         System.out.println(“Fin del consumidor”);                       }
       }
22   }
                                                09/02/2007                       Prog. Distribuida bajo Internet
Interbloqueos
        Interbloqueo = dos o más procesos se están esperando mutuamente
          –   Los hilos utilizan recursos (hard o soft). Ej.- cuentas del banco
          –   Para evitar interferencias los recursos se solicitan antes de su uso, y se
              liberan tras su uso
          –   Si un hilo solicita un recurso asignado a otro hilo, debe esperar
          –   Es posible que A espera un recurso asigando a B, mientras B espera un
              recurso asignado a A
        Nunca podrán salir de esa situación
        Ej
          –   Dos procesos Unix establecen comunicación bidireccional con dos pipes
          –   Cruce de calles con prioridad para ‘derecha libre’
          –   Puente estrecho
          –   Banco cuando bloqueamos sólo las cuentas afectadas por la transferencia
                  pide(from); pide(to); transfiere(n); libera(from); libera(to);




23                                      09/02/2007                        Prog. Distribuida bajo Internet
Análisis del problema
        Condiciones de Coffman (necesarias para interbloqueo)
         –   Exclusión mútua.- queremos compartir recursos que no se pueden
             usar de forma simultánea
         –   Uso y espera.- los recursos se solicitan y obtienen
             progresivamente
         –   No expulsión.- sólo puede liberar un recurso quien lo usa
         –   Espera circular.- espera mútua (ciclo en el GAR)
        Grafo de asignación de recursos (GAR)
         –   Representamos hilos y recursos
         –   Si un hilo solicita un recurso, dibujamos un arco del hilo al recurso
         –   Si un recurso está asignado a un hilo, dibujamos un arco del
             recurso al hilo


24                              09/02/2007                Prog. Distribuida bajo Internet
Solución

        Prevención
         –   Consiste en ‘romper’ alguna de las condiciones de Coffman
         –   En muchos casos costoso o imposible
         –   La más fácil de romper suele ser la espera circular
                 Ej.- En el caso del banco siempre ordenamos las cuentas en
                  orden creciente (pedimos primero la menor, y luego la mayor)
        Evitación.-
         –   Antes de asignar un recurso solicitado, analizamos si
             puede conducir a interbloqueos (algoritmo del banquero)
        Detección
         –   Detección de ciclos en el GAR

25                              09/02/2007              Prog. Distribuida bajo Internet

Más contenido relacionado

La actualidad más candente

Evolución de la Programación
Evolución de la ProgramaciónEvolución de la Programación
Evolución de la ProgramaciónAlessandro Viera
 
arboles avl con codigo en java
arboles avl con codigo en javaarboles avl con codigo en java
arboles avl con codigo en javamarhoz
 
Ejercicios Whule y Do While
Ejercicios Whule y Do WhileEjercicios Whule y Do While
Ejercicios Whule y Do WhileJoshe Varillas
 
Operaciones básicas utilizadas en álgebra relacional
Operaciones básicas utilizadas en álgebra relacionalOperaciones básicas utilizadas en álgebra relacional
Operaciones básicas utilizadas en álgebra relacionalLili Sanchez
 
Tabla comparativa de herramientas case oswaldo mauleon
Tabla comparativa de herramientas case oswaldo mauleon Tabla comparativa de herramientas case oswaldo mauleon
Tabla comparativa de herramientas case oswaldo mauleon oswaldoyuneri
 
Metodologías Para AnáLisis Y DiseñO Orientado A Objetos
Metodologías Para AnáLisis Y DiseñO Orientado A ObjetosMetodologías Para AnáLisis Y DiseñO Orientado A Objetos
Metodologías Para AnáLisis Y DiseñO Orientado A Objetoshector_h30
 
Diagramas UML
Diagramas UMLDiagramas UML
Diagramas UML1da4
 
Modelado del negocio
Modelado del negocioModelado del negocio
Modelado del negociosullinsan
 
Ejercicios de base de datos
Ejercicios de base de datosEjercicios de base de datos
Ejercicios de base de datosMaria Barrios
 
Taller Practico 2 Base de Datos
Taller Practico 2 Base de DatosTaller Practico 2 Base de Datos
Taller Practico 2 Base de Datosjhonfredy2000
 
Ventajas y desventajas de visual studio
Ventajas  y desventajas de visual studioVentajas  y desventajas de visual studio
Ventajas y desventajas de visual studioruthmayhuavale
 
Arquitectura cliente servidor
Arquitectura cliente servidorArquitectura cliente servidor
Arquitectura cliente servidorRichard Castro
 
Diseño de base de datos moo
Diseño de base de datos mooDiseño de base de datos moo
Diseño de base de datos moojosevara
 
Emulador emu8086
Emulador emu8086Emulador emu8086
Emulador emu8086gabo
 

La actualidad más candente (20)

Evolución de la Programación
Evolución de la ProgramaciónEvolución de la Programación
Evolución de la Programación
 
arboles avl con codigo en java
arboles avl con codigo en javaarboles avl con codigo en java
arboles avl con codigo en java
 
Ejercicios Whule y Do While
Ejercicios Whule y Do WhileEjercicios Whule y Do While
Ejercicios Whule y Do While
 
Bases de datos orientadas a objetos
Bases de datos orientadas a objetosBases de datos orientadas a objetos
Bases de datos orientadas a objetos
 
Operaciones básicas utilizadas en álgebra relacional
Operaciones básicas utilizadas en álgebra relacionalOperaciones básicas utilizadas en álgebra relacional
Operaciones básicas utilizadas en álgebra relacional
 
Tabla comparativa de herramientas case oswaldo mauleon
Tabla comparativa de herramientas case oswaldo mauleon Tabla comparativa de herramientas case oswaldo mauleon
Tabla comparativa de herramientas case oswaldo mauleon
 
patron composite
patron compositepatron composite
patron composite
 
Metodologías Para AnáLisis Y DiseñO Orientado A Objetos
Metodologías Para AnáLisis Y DiseñO Orientado A ObjetosMetodologías Para AnáLisis Y DiseñO Orientado A Objetos
Metodologías Para AnáLisis Y DiseñO Orientado A Objetos
 
Diagramas UML
Diagramas UMLDiagramas UML
Diagramas UML
 
Expresiones logicas
Expresiones logicasExpresiones logicas
Expresiones logicas
 
Modelado del negocio
Modelado del negocioModelado del negocio
Modelado del negocio
 
Ejercicios de base de datos
Ejercicios de base de datosEjercicios de base de datos
Ejercicios de base de datos
 
Taller Practico 2 Base de Datos
Taller Practico 2 Base de DatosTaller Practico 2 Base de Datos
Taller Practico 2 Base de Datos
 
Enunciados de casos para Bases de Datos
Enunciados de casos para Bases de DatosEnunciados de casos para Bases de Datos
Enunciados de casos para Bases de Datos
 
Ventajas y desventajas de visual studio
Ventajas  y desventajas de visual studioVentajas  y desventajas de visual studio
Ventajas y desventajas de visual studio
 
Arquitectura cliente servidor
Arquitectura cliente servidorArquitectura cliente servidor
Arquitectura cliente servidor
 
Diseño de base de datos moo
Diseño de base de datos mooDiseño de base de datos moo
Diseño de base de datos moo
 
Emulador emu8086
Emulador emu8086Emulador emu8086
Emulador emu8086
 
Unidad 1 arquitectura de computadoras
Unidad 1 arquitectura de computadorasUnidad 1 arquitectura de computadoras
Unidad 1 arquitectura de computadoras
 
Fundamentos de BD - Unidad 5 algebra relacional
Fundamentos de BD - Unidad 5 algebra relacionalFundamentos de BD - Unidad 5 algebra relacional
Fundamentos de BD - Unidad 5 algebra relacional
 

Similar a Programaci un+concurrente+en+java (20)

Gprocesos
GprocesosGprocesos
Gprocesos
 
Sockets java
Sockets javaSockets java
Sockets java
 
Hilo de ejecución
Hilo de ejecuciónHilo de ejecución
Hilo de ejecución
 
Thread
ThreadThread
Thread
 
Atix23
Atix23Atix23
Atix23
 
Atix23
Atix23Atix23
Atix23
 
Unidad 2. Lenguaje orientado a objetos
Unidad 2. Lenguaje orientado a objetosUnidad 2. Lenguaje orientado a objetos
Unidad 2. Lenguaje orientado a objetos
 
Sistemas Distribuidos conceptos generales
Sistemas Distribuidos conceptos generalesSistemas Distribuidos conceptos generales
Sistemas Distribuidos conceptos generales
 
GUIA 1 HILOS Y PROCESOS
GUIA 1 HILOS Y PROCESOSGUIA 1 HILOS Y PROCESOS
GUIA 1 HILOS Y PROCESOS
 
Lps 17 hilos
Lps 17 hilosLps 17 hilos
Lps 17 hilos
 
Estándares del modelo osi
Estándares del modelo osiEstándares del modelo osi
Estándares del modelo osi
 
Sistema operativo
Sistema operativoSistema operativo
Sistema operativo
 
programacion concurrente java.pptx
programacion concurrente java.pptxprogramacion concurrente java.pptx
programacion concurrente java.pptx
 
Hilos En Java
Hilos En JavaHilos En Java
Hilos En Java
 
Tema 12 hilos en java por gio
Tema 12   hilos en java por gioTema 12   hilos en java por gio
Tema 12 hilos en java por gio
 
Gestionando servidores con Puppet
Gestionando servidores con PuppetGestionando servidores con Puppet
Gestionando servidores con Puppet
 
Sistema operativo de hebras
Sistema operativo de hebrasSistema operativo de hebras
Sistema operativo de hebras
 
Sistemas operativos threads
Sistemas operativos   threadsSistemas operativos   threads
Sistemas operativos threads
 
Modelo osi
Modelo osiModelo osi
Modelo osi
 
2.3 procesos ligeros
2.3 procesos ligeros2.3 procesos ligeros
2.3 procesos ligeros
 

Programaci un+concurrente+en+java

  • 1. Programación Concurrente en Java Curso 2006-2007 9/2/2007 Prog. Distribuida Bajo Internet
  • 2. ¿Qué es la Programación Concurrente?  Diseño basado en varias actividades independientes – Conceptualmente se ejecutan en paralelo  En un nodo, multiplexa el tiempo de procesador entre las tareas  En un sistema distribuido, paralelismo real  Las actividades deben cooperar entre sí – Comunicación – Sincronización  Actividades = procesos o threads (hilos) 2 09/02/2007 Prog. Distribuida bajo Internet
  • 3. Utilidad de la programación concurrente  Mejora las características de: – Flexibilidad – Interactividad – Eficiencia  Facilita el diseño de sistemas – Reactivos (responden a estímulos externos) – Con actividades lógicamente separadas y distintos niveles de prioridad – Con actividades periódicas – Ej.- atención a varios clientes, timeouts, etc. 3 09/02/2007 Prog. Distribuida bajo Internet
  • 4. Dificultades a resolver  Puede darse cualquier intercalado de ejecución  Los programas deben ser correctos bajo cualquier intercalado posible – Ejemplo.- acceso a cuenta bancaria  Posibles interferencias entre tareas – Resultado incorrecto bajo ciertos intercalados (no determinismo)  Vivacidad, interbloqueos 4 09/02/2007 Prog. Distribuida bajo Internet
  • 5. Proceso  Abstracción proporcionada por el SO (ej Unix) – El SO planifica y ejecuta varios procesos  Algoritmo de planificación – Cooperativo (cada proceso se autolimita) – Expulsivo (el sistema limita el tiempo dedicado a cada proceso) – Cada proceso mantiene su propio estado  Pila  Áreas de datos  Ficheros abiertos, etc. – Existe una jerarquía de objetos (relación padre-hijo)  Padre e hijo comparten información – Ficheros abiertos – Pipes y streams – Sockets  Pueden comunicarse/sincronizarse 5 09/02/2007 Prog. Distribuida bajo Internet
  • 6. Thread (Thread=hilo=proceso ligero)  Hilos = Actividades concurrentes dentro de un proceso  Comparten el contexto del proceso padre – Variables compartidas – Ficheros abiertos, etc.  Pero cada hilo mantiene una parte local – Pila local – Variables locales, etc  Creación/destrucción/comunicación/cambio estado mucho más eficiente que con procesos  La memoria compartida facilita la comunicación y sincronización – Pero aparecen posibles interferencias  Nos centramos en hilos (Threads) – Asumimos acceso a variables comunes 6 09/02/2007 Prog. Distribuida bajo Internet
  • 7. Interferencias  Muchas operaciones suponen tanto lecturas como escrituras – Ej.- i++ consiste a bajo nivel en varias operaciones primitivas  r<-[i], inc r, [i]<-r  Esas operaciones no se tratan como atómicas – El planificador puede interrumpirla en cualquier punto, cediendo el control a otro hilo – Puede darse cualquier intercalado de ejecución  Ej dos hilos A, B ejecutan concurrentemente sendas instrucciones i++ – A ejecuta r<-[i] – B ejecuta i++ (todos los pasos) – A ejecuta inc r, [i]<-r – Hemos perdido el cambio introducido por B  Solución – Concepto de sección crítica (exlusión mútua) – Sincronización (reservas, semáforos, monitores, etc.) 7 09/02/2007 Prog. Distribuida bajo Internet
  • 8. ¿Porqué Java?  Incorpora construcciones para Programación Concurrente – Los hilos forman parte del modelo del lenguaje  Aplicación = hilos usuario + hilos sistema (ej.- para GC y GUI)  Hilos usuario.- uno para el método main(), y podemos crear otros  La aplicación termina cuando finalizan todos sus hilos usuario – Facilita el desarrollo de aplicaciones concurrentes  Lenguaje conocido (Prog. Avanzada)  Demandado por el mercado  Además – Facilidades para programación en red  Plataforma de distribución de bajo nivel – Facilidades para Objetos Distribuidos  Plataforma de distribución de nivel intermedio 8 09/02/2007 Prog. Distribuida bajo Internet
  • 9. Prog. Concurrente en Java  Creación de hilos  Ej.- Servidor multi-hilo  Ciclo de vida de los hilos  Estados de un hilo vivo  Sincronización – Exclusión mútua – Espera y notificación  Ejemplo  Interbloqueos 9 09/02/2007 Prog. Distribuida bajo Internet
  • 10. Creación de hilos  Crear nueva clase como extensión de Thread class X extends Thread { … public void run() {..} // codigo del hilo } … X h= new X(); h.start();  Implementar interface Runnable class X implements Runnable { Public void run() {..} // codigo del hilo } .. Thread h= new Thread(new X()); h.start();  La actividad se inicia al aplicar el método start sobre el objeto hilo 10 09/02/2007 Prog. Distribuida bajo Internet
  • 11. Creación de hilos.- ej import java.io.*; public class T extends Thread { protected int n; Public static void main(String[] argv) { for (int i = 0; i<3; i++) new T(i).start(); } public T(int n) {this.n = n;} public void run() { int i = 0; while (count < 5) { System.out.println(“Hilo " + n + " iteracion " + i++); try {sleep((n + 1) * 1000);} catch(InterruptedException e) {e.printStackTrace();} } System.out.println(“El hilo " + n + " ha terminado"); } } 11 09/02/2007 Prog. Distribuida bajo Internet
  • 12. Estructura de un servidor  Servidor secuencial while (msg = getMessage()) Gestiona el mensaje  Servidor concurrente while (msg = getMessage()) Crea nueva tarea para gestionar el mensaje  El servidor concurrente puede atender varios clientes simultáneamente 12 09/02/2007 Prog. Distribuida bajo Internet
  • 13. Ciclo de vida de los hilos new() start() Creado Vivo Stop() Stop(), end() Finalizado 13 09/02/2007 Prog. Distribuida bajo Internet
  • 14. Estados de un hilo vivo start() dispatch Stop() Preparado Ejecución yield() resume() end suspend() sleep(), suspend() Espera 14 09/02/2007 Prog. Distribuida bajo Internet
  • 15. Estados de un hilo vivo  start – inicia la ejecución de ‘run’  isAlive – cierto si tarea iniciada y no finalizada  stop – Finaliza la tarea  suspend – Suspende temporalmente la tarea (hasta ‘resume’)  sleep – Suspende la tarea un periodo especificado (en milisegundos)  join – Suspende hasta que finaliza otra tarea  interrupt – Aborta la espera iniciada con ‘sleep’, ‘wait’ o ‘join 15 09/02/2007 Prog. Distribuida bajo Internet
  • 16. Ejemplo de interferencias  Suponemos un conjunto de cuentas bancarias  Varios hilos utilizan esas cuentas – Cada hilo usa dos cuentas, transfiriendo n unidades de la primera a la segunda – La selección de la cuenta destino y la cantidad son aleatorias – Cada hilo cede el control (yield) en mitad de una transferencia  Simula una posible expulsión por parte del SO  Con ello aumentamos la probabilidad de interferencias  La suma total (valor acumulado de todas las cuentas) debe ser constante 16 09/02/2007 Prog. Distribuida bajo Internet
  • 17. Ejemplo de interferencias import java.io.*; public class Interferencias { class Banco { public static void main(String[] args) { private int[] cuenta; Banco b = new Banco(10, 1000); private long ntransf = 0; for (int i =0; i <numCuentas; i++) public int size() {return cuenta.length; } (new Transf(b, i, sadoInicial)).start(); public Banco(int n, int v0) { } cuenta = new int[n]; ntransf = 0; } for (int i = 0; i < size(); i++) cuenta[i] = v0; class Transf extends Thread { } private Banco banco; private int from, max; public void transfiere(int from, int to, int n) { private int rand(int n) {(int)n*Math.random();} if (cuenta[from] < n) return; public Transf (Banco b, int from, int max) { cuenta[from] -= n; banco = b; This.from = from; this.max = max; Thread.currentThread().yield(); } cuenta[to] += n; if (++ntransf % 10 public void run() { == 0) test(); try { } while (!interrupted()) { public void test() { banco.transfiere(from, int total = 0; rand(banco.size()), rand(max)); for (int i = 0; i<size(); i++) total+= sleep(1); cuenta[i]; } System.out.println("Transferencias:"+ ntransf + 17 } } catch(InterruptedException e) {} 09/02/2007 Prog. Distribuida bajo Internet " Total: " + total); } }
  • 18. Sincronización y exclusión mútua  Las tareas deben cooperar entre sí – Comparten objetos  Ej. una tarea modifica el estado del objeto, otra lo consulta – Pueden haber interferencias  Sólo pueden aparecer en fragmentos de código que acceden a objetos compartidos  Solución = garantizar ejecución secuencial de dichos fragmentos de código = exclusión mútua – Palabra reservada ‘synchronized’  Puede aplicarse a métodos: synchronized void m() {..}  Y a bloques de código: synchronized(objeto) {..}  Se interpreta como una sección crítica que impide la ejecución simultánea de otros métodos sincronizados  La usamos para todo recurso que requiere acceso atómico 18 09/02/2007 Prog. Distribuida bajo Internet
  • 19. Ejemplo revisado  En el ejemplo anterior teníamos problemas de interferencias en el acceso a las cuentas  Usamos synchronized en las funciones que acceden a las cuentas (transferencia y test) public synchronized void transferencia(..) .. public synchronized void test(..) ..  Con ello corregimos el problema  Pero restringimos demasiado la concurrencia – Dos transferencias que trabajan sobre cuentas distintas no pueden interferir entre sí, pero las ejecutamos en exclusión mútua – La solución es restringir el acceso únicamente a las dos cuentas utilizadas por cada hilo 19 09/02/2007 Prog. Distribuida bajo Internet
  • 20. Espera y notificación  Método parcial = método que sólo debe activarse en determinados estados del objeto – Ej.- extraer de una lista (sólo si no vacía)  Métodos parciales en objetos compartidos – Si un hilo invoca un método parcial en un estado incorrecto, debe esperar – Cuando otro hilo modifica el estado debe notificar el cambio a un hipotético hilo en espera (notificación)  Métodos de sincronización – wait.- suspende hilo, libera exclusión mútua – notify.- reactiva uno de los hilos suspendidos por wait – notifyAll.- idem., pero los reactiva todos 20 09/02/2007 Prog. Distribuida bajo Internet
  • 21. Ejemplo de espera y notificación  Productor consumidor – Una hilo genera valores y los inserta en una cola – Otro hilo extrae valores de la cola y los escribe en pantalla – La cola mantiene orden FIFO (first-in first-out)  Implementamos la cola como vector circular – Vector de enteros de talla N  Permite almacenar hasta N valores generados y todavía no consumidos – Tres variables que representan el índice donde insertar, índice donde extraer, y número de elementos (i,e,n) – Operaciones  void put(int x)  int get()  boolean lleno()  boolean vacio() 21 09/02/2007 Prog. Distribuida bajo Internet
  • 22. Ejemplo de espera y notificación public class prodCons { class Buffer { public static void main(char[] args) { private int[] v; Buffer b= new Buffer(4); private int N, n, i, e; (new Productor(b,20)).start(); private boolean lleno() {return n==N;} (new Consumidor(b)).start(); private boolean vacio() {return n==0;} } } public Buffer(int max) { N=max; n=e=i=0; v=new int[N]; class Productor extends Thread { } private int N; public synchronized void put(int x) { public Productor (int max) {N=max;} while (lleno()) wait(); public void run() { v[i]=x; i=(i+1)%N; n++; for (int i=0; i<N; i++) b.put(i); notifyAll(); b.put(-1); System.out.println(“Fin del productor”); } } public synchronized int get() { } while (vacio()) wait(); int x=v[e]; e=(e+1)%N; n--; class Consumidor extends Thread { notifyAll(); public void run() { return x; do{ int x=b.get(); System.out.println(“ “+x); } while (x>=0); } System.out.println(“Fin del consumidor”); } } 22 } 09/02/2007 Prog. Distribuida bajo Internet
  • 23. Interbloqueos  Interbloqueo = dos o más procesos se están esperando mutuamente – Los hilos utilizan recursos (hard o soft). Ej.- cuentas del banco – Para evitar interferencias los recursos se solicitan antes de su uso, y se liberan tras su uso – Si un hilo solicita un recurso asignado a otro hilo, debe esperar – Es posible que A espera un recurso asigando a B, mientras B espera un recurso asignado a A  Nunca podrán salir de esa situación  Ej – Dos procesos Unix establecen comunicación bidireccional con dos pipes – Cruce de calles con prioridad para ‘derecha libre’ – Puente estrecho – Banco cuando bloqueamos sólo las cuentas afectadas por la transferencia  pide(from); pide(to); transfiere(n); libera(from); libera(to); 23 09/02/2007 Prog. Distribuida bajo Internet
  • 24. Análisis del problema  Condiciones de Coffman (necesarias para interbloqueo) – Exclusión mútua.- queremos compartir recursos que no se pueden usar de forma simultánea – Uso y espera.- los recursos se solicitan y obtienen progresivamente – No expulsión.- sólo puede liberar un recurso quien lo usa – Espera circular.- espera mútua (ciclo en el GAR)  Grafo de asignación de recursos (GAR) – Representamos hilos y recursos – Si un hilo solicita un recurso, dibujamos un arco del hilo al recurso – Si un recurso está asignado a un hilo, dibujamos un arco del recurso al hilo 24 09/02/2007 Prog. Distribuida bajo Internet
  • 25. Solución  Prevención – Consiste en ‘romper’ alguna de las condiciones de Coffman – En muchos casos costoso o imposible – La más fácil de romper suele ser la espera circular  Ej.- En el caso del banco siempre ordenamos las cuentas en orden creciente (pedimos primero la menor, y luego la mayor)  Evitación.- – Antes de asignar un recurso solicitado, analizamos si puede conducir a interbloqueos (algoritmo del banquero)  Detección – Detección de ciclos en el GAR 25 09/02/2007 Prog. Distribuida bajo Internet