Académique Documents
Professionnel Documents
Culture Documents
Clase 9 Threads
Ezequiel Aranda
Sun Microsystems Campus
Ambassador
AGENDA
>java.lang.Thread
>java.lang.Runnable
>Instanciacin e inicializacin
de hilos
>Planificacin
>Estados de los hilos
>Sincronizacin, locks y
deadlocks
>Interaccin entre hilos
Extendiendo java.lang.Thread
>Sobrescribir el mtodo run(). Debera ser algo
as:
class MyThread extends Thread {
public void run() {
System.out.println("Important
job running in MyThread"); } }
Implementando java.lang.Runnable
>Implementando Runnable podremos,
adicionalmente, extender de otra clase.
class MyRunnable implements Runnable{
public void run() {
System.out.println("Important
job running in MyRunnable");
}
Instanciando un Thread
>Si extendemos la clase Thread:
MyThread t = new MyThread()
Inicializando un Thread
t.start();
El planificador de threads
>El orden en el cual se ejecutar un conjunto
de threads no est garantizado.
class NameRunnable implements Runnable {
public void run() {
for (int x = 1; x <= 3; x++) {
System.out.println("Run by " +
Thread.currentThread().getName()
+ ", x is " + x);
}
}
}
Estados de un Thread
>New: es el estado en el que se encuentra el
hilo apenas despus de su creacin. En este
punto no se considera que el hilo este vivo.
>Runnable: que un hilo se encuentre en este
estado significa que es elegible para su
ejecucin, pero el planificador an no lo ha
seleccionado. En este punto se considera que
el hilo esta vivo.
NEW
RUNNABLE
RUNNING
DEAD
Sleeping
>sleep() es un mtodo esttico de la clase
Thread.
>Se usa para frenar a un hilo forzandolo a ir al
estado sleeping por una fraccin de tiempo
dada antes de volver a ser elegible para
ejecucin.
try {
Thread.sleep(20*60*1000); //powernap
}
catch (InterruptedException ex) { }
Sleeping (II)
class NameRunnable implements Runnable {
public void run() {
for (int x = 1; x < 4; x++) {
System.out.println("Run by "+
Thread.currentThread().getName());
try {Thread.sleep(1000); }
catch (InterruptedException ex) { }
}
}
}
yield()
>La idea de yield() es la de cambiar el estado
del hilo en ejecucin a runnable, dandole as
la posibilidad de ejecutarse a otros hilos de la
misma prioridad.
>Sin embargo, nada prohbe al planificador
volver a seleccionar para ejecucin al mismo
hilo una y otra vez.
join()
>Si un hilo B necesita que la tarea de un hilo A
se complete para poder comenzar su
ejecucin, necesitamos hacer un join entre
B y A.
>Esto har que B no pueda pasar al estado
runnable hasta que A complete su ejecucin y
pase al estado dead.
join() (II)
En resumen
>sleep(): garantiza que el hilo en ejecucin
pase al estado sleeping por al menos el
tiempo especificado.
>yield(): no garantiza absolutamente nada. Su
funcin es la de volver al hilo en ejecucin al
estado runnable.
>join(): provoca que se detenga la ejecucin
del hilo actual hasta, por lo menos, la
finalizacin del hilo con el que se realiz el
join.
Sincronizacin
>Existe un problema conocido como race condition
>Se da cuando mltiples hilos que pueden acceder a un
mismo recurso.
>Produce datos corruptos cuando los hilos acceden al valor
de los datos entremedio de operaciones que deberan ser
atmicas.
Sincronizacin(II)
>No hay forma de garantizar que un mismo
hilo se mantendr en ejecucin durante toda
la operacin atmica.
>Pero s es posible garantizar que incluso si el
hilo no se mantiene en ejecucin durante la
operacin atmica, ningn otro hilo pueda
actuar sobre los mismos datos.
Sincronizacin (III)
>Entonces Cmo protegemos nuestros
datos?
>Debemos hacer dos cosas
>Hacer privadas a las variables
>Sincronizar el cdigo que modifica las variables.
(utilizando la palabra reservada synchronized).
>Ejemplo:
private synchronized void
makeWithdrawal(int amt)
Sincronizacin y locks
>Cada objeto en java tiene un lock, que se
utiliza cuando el mismo tiene cdigo marcado
como synchronized en alguno de sus
mtodos.
>Cuando ingresamos en un mtodo
sincronizado, no esttico, obtenemos
automticamente el lock de la instancia de la
clase cuyo cdigo estamos ejecutando.
>Es equivalente a:
public void doStuff() {
synchronized(this) {
System.out.println("synchronized");
}
}
Thread Safe
>Cuando los mtodos de una clase han sido
cuidadosamente sincronizados para proteger
los datos de la misma, llamamos a esa clase
Thread Safe.
>Por ejemplo los mtodos de StringBuffer se
encuentran sincronizados, mientras que los
de StringBuilder no lo estn. Esto hace que en
un ambiente multithread sea ms seguro
utilizar StringBuffer.
Deadlock
>Un deadlock ocurre cuando dos hilos se
bloquean mutuamente esperando que el otro
libere el lock que cada uno necesita.
>Ninguno puede
continuar su ejecucin
hasta que el otro libere
el lock por el que
espera, por lo que se
sientan a esperar para
siempre
class ThreadA {
public static void main(String [] args) {
ThreadB b = new ThreadB();
b.start();
synchronized(b) {
try {
System.out.println("Waiting for b
to
complete...");
b.wait();
}
catch (InterruptedException e) {}
System.out.println("Total is:
" +
b.total);
}
}
}
Preguntas