Você está na página 1de 35

Programacin Concurrente en Java: Threads o

Luis Fernando Llana D az


Departamento de Sistemas Informticos y Computacin a o Universidad Complutense de Madrid

7 de mayo de 2007

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Ejemplos de programacin concurrente o

En un sistema operativo, diversos programas compiten por los recursos del sistema: memoria, dispositivos. Bases de datos. Aplicaciones Web.

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Hebras, hilos
En un programa concurrente puede haber varios hilos de computacin. o
h1.start() h2.start() h3.start()

h1.join()

h2.join() h3.join()

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Sincronizacin de Objetos o

Puede haber varias hebras ejecutando simultneamente a mtodos de objetos e Es necesario sincronizar los accesos al objeto.

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Threads
Extendiendo la clase java.lang.Thread.
public class PrThread extends Thread { public PrThread ( String s ) { super ( s ); } public final void run () { boolean sigue = true ; for ( int i =0; i <100 && sigue ; i ++) { try { System . out . println ( getName ()+ " : " + i ); sleep (20); } catch ( I n t e r r u p t e d E x c e p t i o n e ) { System . out . println ( getName ()+ " interrumpida " ); sigue = false ; } } } public static final void main ( final String [] args ){ Thread p = new PrThread ( " mia " ); p . start (); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Threads
Implementado el interfaz java.lang.Runnable.
public class PrRunnable implements Runnable { public final void run () { Thread hebra = Thread . currentThread (); boolean sigue = true ; for ( int i =0; i <100 && sigue ; i ++) { try { System . out . println ( hebra . getName ()+ " : " + i ); hebra . sleep (20); } catch ( I n t e r r u p t e d E x c e p t i o n e ) { System . out . println ( hebra . getName ()+ " interrumpida " ); sigue = false ; } } } public static final void main ( final String [] args ) { Thread p = new Thread ( new PrRunnable () , " mia " ); p . start (); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Ciclo de vida de una hebra

Tras crear una hebra y se ejecuta el mtodo start, la hebra puede e estr: a
1 2

En ejecucin. o Suspendida: ha ejecutado sleep, join, wait.


Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Luis Fernando Llana D az

Programacin Concurrente en Java: Threads o

Parar una hebra

Usar el mtodo interrupt e


public static void ex1 () throws I n t e r r u p t e d E x c e p t i o n { Thread h = new PrThread ( " 1 " ); h . start (); Thread . sleep (100); h . interrupt (); System . out . println ( h . isInterrupted ()); } 1 2 3 4 5 6 7

Mtodos Deprecated: stop, suspend, resume. e Una hebra para cunado est Not Runnnable, ha ejecutado sleep, a join, wait. Pueden lanzar InterruptedException, la hebra deber parar. a

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Esperamos a que una hebra acabe

Mtodo: join e
public static void ex2 () throws I n t e r r u p t e d E x c e p t i o n { Thread h1 = new PrThread ( " 1 " ); Thread h2 = new PrThread ( " 2 " ); Thread h3 = new PrThread ( " 3 " ); h1 . start (); h2 . start (); h3 . start (); h1 . join (); h2 . join (); h3 . join (); } 1 2 3 4 5 6 7 8 9 10 11

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Esperamos a que una hebra acabe


Mtodo: join e
h1.start() h2.start() h3.start()

h1.join()

h2.join() h3.join()

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Esperamos a que una hebra acabe


Mtodo: join e
h1.start() h2.start() h3.start()

h1.start(): h1 se ejecuta.

h1.join()

h2.join() h3.join()

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Esperamos a que una hebra acabe


Mtodo: join e
h1.start() h2.start() h3.start()

1 2

h1.start(): h1 se ejecuta. h2.start(): h2 se ejecuta.

h1.join()

h2.join() h3.join()

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Esperamos a que una hebra acabe


Mtodo: join e
h1.start() h2.start() h3.start()

1 2 3

h1.start(): h1 se ejecuta. h2.start(): h2 se ejecuta. h3.start(): h3 se ejecuta.

h1.join()

h2.join() h3.join()

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Esperamos a que una hebra acabe


Mtodo: join e
h1.start() h2.start() h3.start()

1 2 3 4

h1.start(): h1 se ejecuta. h2.start(): h2 se ejecuta. h3.start(): h3 se ejecuta. h1.join(): esperamos a que h1 pare.

h1.join()

h2.join() h3.join()

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Esperamos a que una hebra acabe


Mtodo: join e
h1.start() h2.start() h3.start()

1 2 3 4

h1.start(): h1 se ejecuta. h2.start(): h2 se ejecuta. h3.start(): h3 se ejecuta. h1.join(): esperamos a que h1 pare. h2.join(): esperamos a que h2 pare.

h1.join()

5
h2.join() h3.join()

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Esperamos a que una hebra acabe


Mtodo: join e
h1.start() h2.start() h3.start()

1 2 3 4

h1.start(): h1 se ejecuta. h2.start(): h2 se ejecuta. h3.start(): h3 se ejecuta. h1.join(): esperamos a que h1 pare. h2.join(): esperamos a que h2 pare. h3.join(): esperamos a que h3 pare (no hace falta).

h1.join()

5
h2.join() h3.join()

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Cerrojos de objetos
Cada objeto en Java tiene un cerrojo
synchronized ( obj ) { /* */ } 1 2 3

Slo pueda haber una hebra propietaria del cerrojo. o Slo una hebra propietaria del cerrojo puede ejecutar un cdigo o o synchronized.

El cerrojo puede abarcar a todo un mtodo e


type method (...) { synchronized ( this ) { /* */ } 1 2 3 4

synchronized type method (...) { /* */ }

1 2 3

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Durmindose/depertndose en un objeto e a
wait() Una hebra que tiene el cerrojo de un objeto puede invocar el mtodo wait() del objeto. e

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Durmindose/depertndose en un objeto e a
wait() Una hebra que tiene el cerrojo de un objeto puede invocar el mtodo wait() del objeto. e La hebra queda suspendida hasta que alguien la despierte. Se libera para que otra hebra pueda adquirirlo. Cuando es liberarla debe adquirir de nuevo el cerrojo para seguir la ejecucin. o wait(tiempo) Igual, pero se queda dormida un tiempo mximo. a

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Durmindose/depertndose en un objeto e a
wait() Una hebra que tiene el cerrojo de un objeto puede invocar el mtodo wait() del objeto. e La hebra queda suspendida hasta que alguien la despierte. Se libera para que otra hebra pueda adquirirlo. Cuando es liberarla debe adquirir de nuevo el cerrojo para seguir la ejecucin. o wait(tiempo) Igual, pero se queda dormida un tiempo mximo. a notify() Una hebra que tiene el cerrojo de un objeto puede invocar el mtodo notify() del objeto. e

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Durmindose/depertndose en un objeto e a
wait() Una hebra que tiene el cerrojo de un objeto puede invocar el mtodo wait() del objeto. e La hebra queda suspendida hasta que alguien la despierte. Se libera para que otra hebra pueda adquirirlo. Cuando es liberarla debe adquirir de nuevo el cerrojo para seguir la ejecucin. o wait(tiempo) Igual, pero se queda dormida un tiempo mximo. a notify() Una hebra que tiene el cerrojo de un objeto puede invocar el mtodo notify() del objeto. e Despierta una hebra suspendida en el objeto. No libera el cerrojo del objeto. notifyAll Igual, pero despierta a todas.
Luis Fernando Llana D az Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o Programacin Concurrente en Java: Threads o

Regiones cr ticas
El acceso a las regiones cr ticas debe ser exclusivo
public void run () { 1 boolean para = false ; 2 while (! para ) { 3 try { 4 ciclo (); 5 } catch ( I n t e r r u p t e d E x c e p t i o n e ) { 6 para = true ; 7 } 8 } 9 } 10 private void ciclo () throws I n t e r r u p t e d E x c e p t i o n { 11 monitor . entrar (); 12 I n t e r r u p t e d E x c e p t i o n salir = null ; 13 try { 14 regCritica (); 15 } catch ( I n t e r r u p t e d E x c e p t i o n e ) { 16 salir = e ; 17 } finally { 18 monitor . salir (); 19 if ( salir != null ) { 20 throw salir ; 21 } 22 int t = random . nextInt ( tiempoDentro ); 23 sleep ( t ); 24 } 25 } 26 Luis Fernando Llana D az Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o Programacin Concurrente en Java: Threads o

Monitor regiones cr ticas

public class Monitor { private int caben ; // caben >=0 public Monitor () { caben =1; } public synchronized void salir () { caben ++; notify (); } public synchronized void entrar () throws I n t e r r u p t e d E x c e p t i o n { while ( caben ==0) wait (); caben - -; } }

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Colecciones sincronizadas
En la clase java.util.Collections encontramos los siguientes mtodos estticos: e a
public static <T > Collection <T > s y n c h r o n i z e d C o l l e c t i o n ( Collection <T > c ) 1

public static <T > Set <T > synchronizedSet ( Set <T > s )

public static <T > SortedSet <T > s y n c h r o n i z e d S o r t e d S e t ( SortedSet <T > s )

public static <T > List <T > synchronizedList ( List <T > list )

public static <K ,V > Map <K ,V > synchronizedMap ( Map <K ,V > m )

public static <K ,V > SortedMap <K ,V > s y n c h r o n i z e d S o r t e d M a p ( SortedMap <K ,V > m )

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Lectores/Escritores I

public void run () { try { monitor . permisoLeer (); lee (); } finally { monitor . finLeer (); } }

1 2 3 4 5 6 7 8

public void run () { try { monitor . permisoEscribir (); escribe (); } finally { monitor . finEscribir (); } }

1 2 3 4 5 6 7 8

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Lectores/Escritores II
package simulacion . l e c t o r e s E s c r i t o r e s ; public class Monitor { private int escrEsperando ; // n m e s c r i t o r e s e s p e r a n d o u private int numLect ; // n m lectores leyendo u private int numEscr ; // n m e s c r i t o r e s e s c r i b i e n d o u // escrEsperando >= numEscr , 0 <= numEscr <=1 numLect >=0 , nunLect >0 ---> numEscr =0 public Monitor () { escrEsperando =0; numLect =0; numEscr =0; } public synchronized void permisoLeer () throws I n t e r r u p t e d E x c e p t i o n { while ( numEscr >0 || escrEsperando >0) wait (); numLect ++; } public synchronized void finLeer () { numLect - -; notifyAll (); } public synchronized void permisoEscribir () throws I n t e r r u p t e d E x c e p t i o n { escrEsperando ++; while ( numLect >0) wait (); numEscr ++; } public synchronized void finEscribir () { escrEsperando - -; numEscr - -; } } Luis Fernando Llana D az 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Lectores/Escritores III

package simulacion . l e c t o r e s E s c r i t o r e s ; 1 import soporte . Aleatorio ; 2 public class G e n e r a d o r L e c t o r e s extends Thread { 3 private double tMedioLlegada ; 4 private int tLeyendo ; 5 private int tMaxSimulacion ; 6 private Aleatorio aleatorio ; 7 private Monitor monitor ; 8 public G e n e r a d o r L e c t o r e s ( double tllegada , int tleyendo , int tmax , int semilla 9 Mon , tMedioLlegada = tllegada ; tLeyendo = tleyendo ; tMaxSimulacion = tmax ; 10 aleatorio = new Aleatorio ( semilla ); 11 monitor = m ; 12 } 13 public void run () { 14 System . out . println ( " Empezando la generaci n de lectores " ); o 15 try { 16 while ( true ) { 17 int sigCoche = aleatorio . poisson ( tMedioLlegada ); 18 this . sleep ( sigCoche *1000); 19 Lector lector = new Lector ( Simulador . sigUsuario () , tLeyendo , monitor ); 20 System . out . println ( " Comenzando " + lector ); 21 lector . start (); 22 } 23 } catch ( I n t e r r u p t e d E x c e p t i o n e ) {} 24 System . out . println ( " Simulaci n lectores finalizada " ); o 25 } 26 } 27 Luis Fernando Llana D az Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Lectores/Escritores IV
package simulacion . l e c t o r e s E s c r i t o r e s ; 1 class Simulador { 2 private static int numUsuario = -1; 3 private static long horaInicio ; 4 public synchronized static int sigUsuario () { 5 numUsuario ++; 6 return numUsuario ; 7 } 8 public Simulador ( double tLlegadaLect , double tLlegadaEscr , 9 int tLeyendo , int tEscribiendo , int tMax ) 10 throws I n t e r r u p t e d E x c e p t i o n { 11 Monitor monitor = new Monitor (); 12 G e n e r a d o r L e c t o r e s generaLectores = 13 new G e n e r a d o r L e c t o r e s ( tLlegadaLect , tLeyendo , tMax , 1111 , monitor ); 14 G e n e r a d o r E s c r i t o r e s generaEscritores = 15 new G e n e r a d o r E s c r i t o r e s ( tLlegadaEscr , tEscribiendo , tMax , 3333 , monitor 16 ); generaLectores . start (); 17 generaEscritores . start (); 18 horaInicio = System . c u r r e n t T i m e M i l l i s (); 19 Thread . sleep ( tMax *1000); 20 generaLectores . interrupt (); 21 generaEscritores . interrupt (); 22 generaLectores . join (); 23 generaEscritores . join (); 24 } 25 public static void main ( String [] args ) throws Exception { 26 Simulador s = new Simulador (2 , 8 , 1 , 2 , 30); 27 } 28 } 29 Luis Fernando Llana D az Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o Programacin Concurrente en Java: Threads o

Filsofos I o

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Filsofos II o

while ( true ) { piensa (); mesa . pideTenedores (); come (); mesa . cedeTenedores (); }

1 2 3 4 5 6

comiendo[i]

true lsofo i est comiendo o a false lsofo i NO est comiendo o a

INV comiendo[i] comiendo[i 1 ] comiendo[i 1 ]

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Filsofos III o

public class Mesa { private int numFilosofos ; private boolean [] comiendo ; public Mesa ( int n ) { numFilosofos = n ;; comiendo = new boolean [ numFilosofos ]; for ( int i = 0; i < numFilosofos ; i ++) { comiendo [ i ] = false ; } } /* p e r m i s o C o m e r ( int i ) y c e d e P e r m i s o ( int i ) */ }

1 2 3 4 5 6 7 8 9 10

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Filsofos IV o

public synchronized void permisoComer ( int i ) throws I n t e r r u p t e d E x c e p t i o n { while ( comiendo [ ant ( i )] || comiendo [ sig ( i )]) { wait (); } comiendo [ i ]= true ; } public synchronized void cedePermiso ( int i ) { comiendo [ i ]= false ; notifyAll (); } public int sig ( int i ) { return ( i +1) % numFilosofos ; } public int ant ( int i ) { return ( i -1+ numFilosofos ) % numFilosofos ; }

1 2 3 4 5 6 7 8 9 10 11 12 13

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Filsofos V o
public class Filosofo extends Thread { private Random random ; private int tiempoComiendo , tiempoPensando ; private Mesa mesa ; private int id ; public Filosofo ( Random r , int tc , int tp , Mesa m , int i ) { random = r ; tiempoPensando = tp ; tiempoComiendo = tc ; mesa = m ; id = i ; } public void run () { boolean para = false ; while (! para ) { try { ciclo (); } catch ( I n t e r r u p t e d E x c e p t i o n e ) { para = true ; } } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Filsofos VI o
private void ciclo () throws I n t e r r u p t e d E x c e p t i o n { piensa ( id , tiempoPensando ); mesa . permisoComer ( id ); try { come ( id , tiempoComiendo ); } catch ( I n t e r r u p t e d E x c e p t i o n e ) { mesa . cedePermiso ( id ); throw e ; } mesa . cedePermiso ( id ); } private void espera ( int tiempo ) throws I n t e r r u p t e d E x c e p t i o n { int t = random . nextInt ( tiempo ); sleep ( t ); } private void piensa ( int id , int tiempo ) throws I n t e r r u p t e d E x c e p t i o n { System . out . println ( " El fil sofo " + id + " empieza a pensar " ); o espera ( tiempo ); System . out . println ( " El fil sofo " + id + " acaba de pensar " ); o } private void come ( int id , int tiempo ) throws I n t e r r u p t e d E x c e p t i o n { System . out . println ( " El fil sofo " + id + " empieza a comer " + " : " + mesa ); o espera ( tiempo ); System . out . println ( " El fil sofo " + id + " acaba de comer " + " : " + mesa ); o } } Luis Fernando Llana D az 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Filsofos VII o
public static void main ( String [] args ) throws I n t e r r u p t e d E x c e p t i o n { int numFilosofos = 5; int tiempoPensando = 1000; int tiempoComiendo = 2000; int tiempoParada = 10000; Random r = new Random (); Mesa mesa = new Mesa ( numFilosofos ); Filosofo [] filosofo = new Filosofo [ numFilosofos ]; for ( int i = 0; i < numFilosofos ; i ++) { filosofo [ i ] = new Filosofo (r , tiempoComiendo , tiempoPensando , mesa , i ); filosofo [ i ]. start (); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 for ( int i = 0; i < numFilosofos ; i ++) { 15 Thread . sleep ( tiempoParada ); 16 System . out . println ( " Parando fil sofo " + i + " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 o " ); filosofo [ i ]. interrupt (); 18 } 19 for ( int i = 0; i < numFilosofos ; i ++) { 20 filosofo [ i ]. join (); 21 } 22 23

Luis Fernando Llana D az

Departamento de Sistemas Informticos y ComputacinUniversidad Complutense de Madrid a o

Programacin Concurrente en Java: Threads o

Você também pode gostar