Escolar Documentos
Profissional Documentos
Cultura Documentos
HILOS
2.1 Procesos
2.1.1 Ciclo de vida de un proceso
En la Figura 1 puede apreciarse el ciclo de vida que suele seguir un proceso.
Este ciclo de vida es prcticamente estndar en todos los SSOO.
Creado
es su turno
Listo Ejecucin Terminado
fin de turno o abandono
voluntario
espera suceso
ocurre suceso
Bloqueado
1
Suelen ser las traducciones ms aceptadas del trmino ingls thread. A lo largo de este libro
utilizaremos el trmino hilo. Usaremos Thread cuando hagamos referencia a la clase con ese nombre en
Java.
cdigo del SO
datos del SO
ID del proceso
Tabla de seales
Mapa de memoria
prioridad
pila
...
Estado de la CPU
2.2 Hilos
Aunque el concepto de hilo lleva existiendo varias dcadas, no ha sido hasta
los 90 cuando ha alcanzado una cierta mayora de edad. Mientras que a
comienzos de los 90 el uso de hilos se circunscriba a la investigacin en
universidades y al desarrollo en sectores industriales especficos, a finales de
los 90 y en el nuevo milenio, el uso de hilos est ampliamente extendido. La
procesos hilos
...
espacio de usuario
t1 h2 h1 h2 h3 h4 h1 h2 h3
PCB PCB PCB
espacio del P1 P2 P3
ncleo
usa
espacio de usuario
er
1 nivel de
planificacin
2 nivel de planificacin
hardware
P1 P2 P3 P4
Con esto daramos por terminada la discusin sobre hilos en general y nos
adentramos en el mundo de los hilos en Java, es decir, en el mundo de los
hilos desde una perspectiva de programador de aplicaciones y no de Sistema
Operativo.
B H
E
main()
F
C
Sin embargo, si desde el hilo principal se crean por ejemplo dos hilos
tendremos algo como lo representado en la Figura 9, en la que se puede ver
cmo el programa se est ejecutando al mismo tiempo por tres sitios distintos:
el hilo principal ms los dos hilos creados. Los hilos pueden estar ejecutando
cdigo en diferentes objetos, cdigo diferente en el mismo objeto o incluso el
mismo cdigo en el mismo objeto y al mismo tiempo.
Es necesario en este punto ver la diferencia entre objeto e hilo. Un objeto es
algo esttico, tiene una serie de atributos y mtodos. Quien realmente ejecuta
esos mtodos es el hilo de ejecucin. En ausencia de hilos slo hay un hilo que
va recorriendo los objetos segn se van produciendo las llamadas entre
mtodos de los objetos. Podra darse el caso del objeto E en la Figura 9, donde
es posible que tres hilos de ejecucin distintos estn ejecutando el mismo
mtodo al mismo tiempo.
B H
E
main()
C F
Hasta aqu lo nico que hemos hecho es crear una clase. Los objetos
pertenecientes a esa clase sern hilos. En las siguientes lneas, desde el
programa principal creamos dos objetos que son hilos, a y b.
Hasta aqu los hilos estn creados, pero no han sido puestos en ejecucin.
Para ponerlos en ejecucin hay que invocar el mtodo start(). Este mtodo
pertenece a la clase Thread. Se encarga de hacer algunas inicializaciones
propias del hilo y posteriormente invoca al mtodo run(). Es decir, invocando
start, se ejecutan en orden los mtodos start (heredado) y run (redefinido)
Las lneas siguientes habra que aadirlas al programa principal y ya
tendramos nuestro primer programa con hilos en Java.
a.start();
b.start();
System.out.println (Fin del hilo principal)
}
Hasta aqu simplemente hemos creado una clase. Al contrario que antes, los
objetos de esta clase no sern hilos pues no hemos heredado de la clase
Como vemos, en la implementacin del mtodo run() hay que controlar quin
es el hilo que se est ejecutando. Para ello nos servimos del mtodo
currentThread() de la clase Thread. Este mtodo nos devuelve una referencia al
hilo que est ejecutando ese cdigo. Esto se hace para evitar que cualquier
mtodo de un hilo distinto haga una llamada a run() directamente, como ocurre
en el siguiente caso.
ejecucin
por intento de adquirir el espera por por adquisicin del cerrojo del objeto
cerrojo de un objeto
synchronized
terminado
Ante una definicin tan vaga como esta uno se puede preguntar cmo es
posible escribir cdigo portable y, lo que es peor, el comportamiento que tendr
la aplicacin dependiendo del sistema subyacente. Ante esto, lo que el
programador no debe hacer es ningn tipo de suposicin y ponerse siempre en
el peor de los casos:
Se debe asumir que los hilos pueden intercalarse en cualquier punto en
cualquier momento.
Nuestros programas no deben estar basados en la suposicin de que
vaya a haber un intercalado entre los hilos. Si esto es un requisito en
nuestra aplicacin, deberemos introducir el cdigo necesario para que
esto sea as.
Prioridades
Las prioridades de cada hilo en Java estn en el rango de 1 (MIN_PRIORITY) a
10 (MAX_PRIORITY). La prioridad de un hilo es inicialmente la misma que la
del hilo que lo cre. Por defecto todo hilo tiene la prioridad 5
(NORM_PRIORITY). El planificador siempre pondr en ejecucin aquel hilo con
mayor prioridad (teniendo en cuenta lo dicho en el punto anterior) Los hilos de
prioridad inferior se ejecutarn cuando estn bloqueados los de prioridad
superior.
Las prioridades se pueden cambiar utilizando el mtodo setPriority
(nuevaPrioridad). La prioridad de un hilo en ejecucin se puede cambiar en
cualquier momento. El mtodo getPriority() devuelve la prioridad de un hilo.
El mtodo yield()hace que el hilo actualmente en ejecucin ceda el paso de
modo que puedan ejecutarse otros hilos listos para ejecucin. El hilo elegido
puede ser incluso el mismo que ha dejado paso, si es el de mayor prioridad.
En el siguiente programa se puede ver cmo se crean dos hilos (t1 y t2) y al
primero de ellos se le cambia la prioridad. Esto hara que t2 acaparase el
procesador hasta finalizar pues nunca ser interrumpido por un hilo de menor
prioridad.
String palabra;
Hilos daemon
Antes de lanzar un hilo, ste puede ser definido como un Daemon, indicando
que va a hacer una ejecucin continua para la aplicacin como tarea de fondo.
Entonces la mquina virtual abandonar la ejecucin cuando todos los hilos
que no sean Daemon hayan finalizado su ejecucin. Los hilos Daemon tienen
la prioridad ms baja. Se usa el mtodo setDaemon(true) para marcar un hilo
como hilo demonio y se usa getDaemon() para comprobar ese indicador. Por
defecto, la cualidad de demonio se hereda desde el hilo que crea el nuevo hilo.
No puede cambiarse despus de haber iniciado un hilo.
La propia MVJ pone en ejecucin algunos hilos daemon cuando ejecutamos
un programa. Entre ellos cabe destacar el garbage collector o recolector de
basura, que es el encargado de liberar la memoria ocupada por objetos que ya
no estn siendo referenciados.
Atributos
public static final int MIN_PRIORITY
La prioridad mnima que un hilo puede tener.
Constructores
public Thread ()
Crea un nuevo objeto Thread. Este constructor tiene el
mismo efecto que Thread (null, null, gname), donde gname
es un nombre generado automticamente y que tiene la
forma Thread-+n, donde n es un entero asignado
consecutivamente.
public Thread (String name)
Crea un nuevo objeto Thread, asignndole el nombre
name.
public Thread (Runnable target)
Crea un nuevo objeto Thread. target es el objeto que
contiene el mtodo run() que ser invocado al lanzar el
hilo con start().
public Thread (Runnable target, String name)
Crea un nuevo objeto Thread, asignndole el nombre
name. target es el objeto que contiene el mtodo run()
que ser invocado al lanzar el hilo con start().
Mtodos
public static Thread currentThread ()
Retorna una referencia al hilo que se est ejecutando
actualmente.
public static void dumpStack ()
Imprime una traza del hilo actual. Usado slo con
propsitos de depuracin..
public String getName ()
Retorna el nombre del hilo.
int getPriority ()
Retorna la prioridad del hilo.
public final boolean isAlive ()
Chequea si el hilo est vivo. Un hilo est vivo si ha sido
lanzado con start y no ha muerto todava.
public final void isDaemon ()
Devuelve verdadero si el hilo es daemon.
public final void join () throws InterruptedException
Espera a que este hilo muera.
public final void join (long millis) throws InterruptedException
Espera como mucho millis milisegundos para que este
hilo muera.
public final void join (long millis, int nanos) throws InterruptedException
Permite afinar con los nanosegundos nanos el tiempo a
esperar.
public void run ()
Si este hilo fue construido usando un objeto que
implementaba Runnable, entonces el mtodo run de ese
M.E Carmen Cern G. Programacin Concurrente BUAP 38
objeto es llamado. En cualquier otro caso este mtodo
no hace nada y retorna.
public final void setDaemon (boolean on)
Marca este hilo como daemon si el parmetro on es
verdadero o como hilo de usuario si es falso. El mtodo
debe ser llamado antes de que el hilo sea lanzado.
public final void setName (String name)
Cambia el nombre del hilo por name.
public final void setPriority (int newPriority)
Asigna la prioridad newPriority a este hilo.
public static void sleep (long millis) throws InterruptedException
Hace que el hilo que se est ejecutando actualmente
cese su ejecucin por los milisegundos especificados en
millis. Pasa al estado dormido. El hilo no pierde la
propiedad de ningn cerrojo que tuviera adquirido con
synchronized.
public static void sleep (long millis, int nanos) throws InterruptedException
Permite afinar con los nanosegundos nanos el tiempo a
estar dormido.
public void start ()
Hace que este hilo comience su ejecucin. La MVJ
llamar al mtodo run de este hilo.
public String toString ()
Devuelve una representacin en forma de cadena de
este hilo, incluyendo su nombre, su prioridad y su grupo.
public static void yield ()
Hace que el hilo que se est ejecutando actualmente
pase al estado listo, permitiendo a otro hilo ganar el
procesador.
2.4 Resumen
En este captulo hemos visto los conceptos fundamentales sobre procesos e
hilos que necesitamos desde el punto de vista de la programacin concurrente.
Con respecto a los procesos, hemos visto su ciclo de vida y su disposicin en
memoria, adentrndonos en el modelo de procesos de Pascal-FC y la gestin y
planificacin de procesos que hace. Con respecto a los hilos, hemos visto los
diferentes estndares que se pueden encontrar (Win32, OS/2 y posix), dos
posibles implementaciones (a nivel de usuario o a nivel de ncleo) y cmo es la
planificacin de hilos en un SO moderno como Solaris. Posteriormente nos
hemos adentrado en el mundo de los hilos en Java. Hemos visto la diferencia
entre hilo y objeto, diferentes formas de crear hilos, el ciclo de vida de un hilo y
su planificacin y prioridades. Finalmente se han mostrado los mtodos ms
usados e importantes de la clase Thread de Java.
Con todo lo visto en este captulo y en el anterior ya estamos en disposicin
de analizar en mayor profundidad los problemas inherentes a la programacin
concurrente y sus posibles soluciones utilizando distintas primitivas de
sincronizacin.