Documente Academic
Documente Profesional
Documente Cultură
24 de abril de 2008
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Hebras, hilos
En un programa concurrente puede haber varios hilos de
computación.
h1
h2
h3
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Sincronización de Objetos
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Threads
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Threads
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Ciclo de vida de una hebra
running
yield
Dead
Se crea la hebra.
La hebra está en ejecución. Se ejecuta el método start.
La hebra se suspende: ha ejecutado sleep, join, wait.
La hebra finaliza. El método run finaliza.
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Esperamos a que una hebra acabe
Método: join
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 { 1
Thread h1 = new PrThread ( " 1 " ); 2
Thread h2 = new PrThread ( " 2 " ); 3
Thread h3 = new PrThread ( " 3 " ); 4
h1 . start (); 5
h2 . start (); 6
h3 . start (); 7
h1 . join (); 8
h2 . join (); 9
h3 . join (); 10
} 11
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
1 h1.start(): h1 se ejecuta.
h1
h2 2 h2.start(): h2 se ejecuta.
h3
3 h3.start(): h3 se ejecuta.
4 h1.join(): esperamos a
que h1 pare.
5 h2.join(): esperamos a
que h2 pare.
6 h3.join(): esperamos a
que h3 pare (no hace falta).
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Cerrojos de objetos
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Durmiéndose/depertándose en un objeto
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Colecciones sincronizadas
public static <T > Set <T > synchronizedSet ( Set <T > s ) 1
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 ) 1
public static <T > List <T > synchronizedList ( List <T > list ) 1
public static <K ,V > Map <K ,V > synchronizedMap ( Map <K ,V > m ) 1
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 ) 1
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Lectores/Escritores I
public void run () { 1
try { 2
monitor . permisoLeer (); 3
lee (); 4
} finally { 5
monitor . finLeer (); 6
} 7
} 8
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Lectores/Escritores II
package simulacion . l ec t or es E sc r it or e s ; 1
public class Monitor { 2
private int escrEsperando ; // núm e s c r i t o r e s e s p e r a n d o 3
private int numLect ; // núm lectores leyendo 4
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 5
// escrEsperando >= numEscr , 0 <= numEscr <=1 numLect >=0 , nunLect >0 - -- > numEscr =0 6
public Monitor () { 7
escrEsperando =0; numLect =0; numEscr =0; 8
} 9
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 { 10
while ( numEscr >0 || escrEsperando >0) wait (); 11
numLect ++; 12
} 13
public synchronized void finLeer () { 14
numLect - -; 15
notifyAll (); 16
} 17
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 { 18
escrEsperando ++; 19
while ( numLect >0) wait (); 20
numEscr ++; 21
} 22
public synchronized void finEscribir () { 23
escrEsperando - -; 24
numEscr - -; 25
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Lectores/Escritores III
} 26
} 27
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Lectores/Escritores IV
package simulacion . l ec t or es E sc r it or e s ; 1
import soporte . Aleatorio ; 2
public class Gen erad orL ect ore 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 Ge ner ado rLe ctor es ( double tllegada , int tleyendo , int tmax , int semilla , 9Monitor m ){
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 " ); 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 " ); 25
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Lectores/Escritores V
} 26
} 27
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Lectores/Escritores VI
package simulacion . l ec t or es E sc r it or 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
Ge nera dor Lec tor e s generaLectores = 13
new Gen era dor Lect ore s ( tLlegadaLect , tLeyendo , tMax , 1111 , monitor ); 14
G e n e r ad o r E s c r i t or e s generaEscritores = 15
new G e n e r a d o rE s c r i t o r e s ( tLlegadaEscr , tEscribiendo , tMax , 3333 , monitor ); 16
generaLectores . start (); 17
generaEscritores . start (); 18
horaInicio = System . cur ren tTim eMi lli s (); 19
Thread . sleep ( tMax *1000); 20
generaLectores . interrupt (); 21
generaEscritores . interrupt (); 22
generaLectores . join (); 23
generaEscritores . join (); 24
} 25
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Lectores/Escritores VII
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Filósofos I
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Filósofos II
while ( true ) { 1
piensa (); 2
mesa . pideTenedores (); 3
come (); 4
mesa . cedeTenedores (); 5
} 6
true filósofo i está comiendo
comiendo[i]
false filósofo i NO está comiendo
INV ≡ comiendo[i] → ¬comiendo[i ⊕ 1 ] ∧ ¬comiendo[i 1 ]
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Filósofos III
public class Mesa { 1
private int numFilosofos ; 2
private boolean [] comiendo ; 3
public Mesa ( int n ) { 4
numFilosofos = n ;; 5
comiendo = new boolean [ numFilosofos ]; 6
for ( int i = 0; i < numFilosofos ; i ++) { comiendo [ i ] = false ; } 7
} 8
/* 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 ) */ 9
} 10
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Filósofos IV
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 { 1
while ( comiendo [ ant ( i )] || comiendo [ sig ( i )]) { wait (); } 2
comiendo [ i ]= true ; 3
} 4
5
public synchronized void cedePermiso ( int i ) { 6
comiendo [ i ]= false ; 7
notifyAll (); 8
} 9
10
public int sig ( int i ) { return ( i +1) % numFilosofos ; } 11
12
public int ant ( int i ) { return ( i -1+ numFilosofos ) % numFilosofos ; } 13
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Filósofos V
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Filósofos VI
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Filósofos VII
} 26
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads
Filósofos VIII
Luis Fernando Llana Dı́az Departamento de Sistemas Informáticos y ComputaciónUniversidad Complutense de Madrid
Programación Concurrente en Java: Threads