Você está na página 1de 17

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

Programacin Concurrente con Java


Modesto Toms Saavedra
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Conceptos Bsicos Java Conceptos Bsicos Sobre Hilos Clases Relacionadas con los Hilos Creacin de Hilos Estado y Control de un Hilo a. Estado de un hilo b. Control de un hilo Planificacin y Prioridad de Hilos a. Scheduling (planificacin) b. Prioridad Sincronizacin a. Ejemplo: problema del productor-consumidor b. Monitores Hilos Daemon Conclusiones Bibliografa

1. Java
Cuando se escribe un programa, en la mayora de los lenguajes de programacin, es necesario decidir el procesador y sistema operativo en los que se va a ejecutar, porque stos lenguajes incluyen llamadas a funciones especficas de una biblioteca asociada al sistema operativo de la plataforma destino. Cuando se est preparado para probar el programa, se enva el cdigo fuente a un compilador que lo transforma en un conjunto de instrucciones propias de la plataforma destino. Por ejemplo, Windows se ejecuta generalmente en un procesador Intel, como un Pentiunm, mientras que los Macintosh utilizan procesadores Motorola 68000 o PowerPC. Cuando se escribe en Java, no necesitamos pensar en llamadas a Windows, Mac OS, u otras bibliotecas del sistema operativo. Java tiene sus propias bibliotecas, llamadas paquetes, que son independientes de la plataforma. Por ello no es necesario preocuparse si la aplicacin se va a ejecutar en una plataforma Intel, una PowerPC o una SPARC. El compilador de Java no genera instrucciones nativas, en su lugar genera los llamados "cdigo de byte" (byte code) para la Mquina Virtual Java (Java Virtual Machine o JVM), que es una mquina que no existe fsicamente. Sun Microsystems (creadores de Java) y otras empresas han desarrollado versiones software de la JVM para una gran parte de las plataformas existentes en el mercado, es decir cada plataforma tiene su propia mquina virtual de Java, y es sta la que ejecuta los byte code. En Java podemos distinguir dos tipos de programas, las aplicaciones autosuficientes que son conocidas como aplicaciones y los que se ejecutan con la ayuda de otro programa (un navegador Web), que se conocen como applets. Las caractersticas principales que nos ofrece Java respecto a cualquier otro lenguaje de programacin son:

1 de 17

16/10/2012 20:04

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

Java es simple
Java ofrece toda la funcionalidad de un lenguaje potente, pero sin las caractersticas menos usadas y ms confusas de stos. C++ es un lenguaje que adolece de falta de seguridad, pero C y C++ son lenguajes ms difundidos, por ello Java se dise para ser parecido a C++ y as facilitar un rpido y fcil aprendizaje. Java elimina muchas de las caractersticas de otros lenguajes como C++, para mantener reducidas las especificaciones del lenguaje y aadir caractersticas muy tiles como el garbage collector (recolector de memoria dinmica). No es necesario preocuparse de liberar memoria, el recolector se encarga de ello y como es un thread (hilo de ejecucin) de baja prioridad, cuando entra en accin, permite liberar bloques de memoria muy grandes, lo que reduce la fragmentacin de la memoria. Java reduce en un 50% los errores ms comunes de programacin con lenguajes como C y C++ al eliminar muchas de las caractersticas de stos, entre las que destacan: aritmtica de punteros no existen referencias registros (struct) definicin de tipos (typedef)

Java es orientado a objetos


Java implementa la tecnologa bsica de C++ con algunas mejoras y elimina algunas cosas para mantener el objetivo de la simplicidad del lenguaje. Java trabaja con sus datos como objetos. Soporta las tres caractersticas propias del paradigma de la orientacin a objetos: encapsulacin, herencia y polimorfismo. Las plantillas de objetos son llamadas, como en C++, clases y sus copias, instancias. Estas instancias, como en C++, necesitan ser construidas y destruidas en espacios de memoria.

Java es distribuido
Java se ha construido con extensas capacidades de interconexin TCP/IP. Existen libreras de rutinas para acceder e interactuar con protocolos como http y ftp. Esto permite a los programadores acceder a la informacin a travs de la red con tanta facilidad como a los ficheros locales. La verdad es que Java en s no es distribuido, sino que proporciona las libreras y herramientas para que los programas puedan ser distribuidos, es decir, que se ejecuten en vanas mquinas, interactuando.

Java es multiplataforma
Para establecer Java como parte integral de la red, el compilador Java compila su cdigo a un fichero objeto de formato independiente de la arquitectura de la mquina en que se ejecutar. Cualquier mquina que tenga el sistema de ejecucin (run-time) puede ejecutar ese cdigo objeto, sin importar en modo alguno la mquina en que ha sido generado. Actualmente existen sistemas run time para Solaras 2.x, SunOs 4.1.x, Windows 95/98, Windows NT, Linux, Irix, Aix, Mac, Apple y probablemente haya grupos de desarrollo trabajando en el paso a otras plataformas. El cdigo fuente Java se "compila" a un cdigo de bytes de bajo nivel independiente

2 de 17

16/10/2012 20:04

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

de la mquina. Este cdigo (byte code) est diseado para ejecutarse en una mquina hipottica que es implementada por un sistema run-time, que s es dependiente de la mquina.

Java es robusto
Java realiza verificaciones en busca de problemas tanto en tiempo de compilacin como en tiempo de ejecucin. La comprobacin de tipos en Java ayuda a detectar errores, lo antes posible, en el ciclo de desarrollo. Java obliga a la declaracin explcita de mtodos, reduciendo as las posibilidades de error. Maneja la memoria para eliminar las preocupaciones por parte del programador de la liberacin o corrupcin de memoria. Tambin implementa los arrays autnticos, en vez de listas enlazadas de punteros, con comprobacin de lmites, para evitar la posibilidad de sobreescribir o corromper memoria resultado de punteros que sealan a zonas equivocadas. Estas caractersticas reducen drsticamente el tiempo de desarrollo de aplicaciones en Java.

Java es seguro
La seguridad en Java tiene dos facetas. En el lenguaje, caractersticas como los punteros o el casting implcito que hacen los compiladores de C y C++ se eliminan para prevenir el acceso ilegal a la memoria. Otra laguna de seguridad u otro tipo de ataque, es el Caballo de Troya. Se presenta un programa como una utilidad, resultando tener una funcionalidad destructiva. El cdigo Java pasa muchos tests antes de ejecutarse en una mquina. El cdigo se pasa a travs de un verificador de byte codes que comprueba el formato de los fragmentos de cdigo y aplica un probador de teoremas para detectar fragmentas de cdigo ilegal, cdigo que falsea punteros, viola derechos de acceso sobre objetos o intenta cambiar el tipo o clase de un objeto. Si los byte codes pasan la verificacin sin generar ningn mensaje de error, entonces sabemos que: El cdigo no produce desbordamiento de operandos en la pila. El tipo de los parmetros de todos los cdigos de operacin son conocidos y correctos. No ha ocurrido ninguna conversin ilegal de datos, tal como convertir enteros en punteros. El acceso a los campos de un objeto se sabe que es legal. No hay ningn intento de violar las reglas de acceso y seguridad establecidas El Cargador de Clases tambin ayuda a Java a mantener su seguridad, separando el espacio de nombres del sistema de ficheros local, del de los recursos procedentes de la red. Esto limita cualquier aplicacin del tipo Caballo de Troya, ya que las clases se buscan primero entre las locales y luego entre las procedentes del exterior. Las clases importadas de la red se almacenan en un espacio de nombres privado, asociado con el origen. Cuando una clase del espacio de nombres privado accede a otra clase, primero se busca en las clases predefinidas (del sistema local) y luego en el espacio de nombres de la clase que hace la referencia. Esto imposibilita que una clase suplante a una predefinida. En resumen, las aplicaciones de Java resultan extremadamente seguras, ya que no acceden a zonas delicadas de memoria o de sistema, con lo cual evitan la interaccin de ciertos virus. Java no posee una semntica especfica para modificar la pila de programa, la memoria libre o utilizar objetos y mtodos de un programa sin los privilegios del ncleo del sistema operativo. Adems, para evitar modificaciones por

3 de 17

16/10/2012 20:04

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

parte de los crackers de la red, implementa un mtodo seguro de autentificacin por clave pblica. El Cargador de clases puede verificar una firma digital antes de realizar una instancia de un objeto. Por tanto, ningn objeto se crea y almacena en memoria, sin que se validen los privilegios de acceso. Es decir, la seguridad se integra en el momento de compilacin, con el nivel de detalle y de privilegio que sea necesario. Dada, pues la concepcin del lenguaje y si todos los elementos se mantienen dentro del estndar marcado por Sun, no hay peligro. Java imposibilita, tambin, abrir ningn fichero de la mquina local (siempre que se realizan operaciones con archivos, stas trabajan sobre el disco duro de la mquina de donde parti el applet), no permite ejecutar ninguna aplicacin nativa de _una plataforma (desde un applet) e impide que se utilicen otros ordenadores como puente, es decir, nadie puede utilizar nuestra mquina para hacer peticiones o realizar operaciones con otraAdems, los intrpretes que incorporan los navegadores de la Web son an ms restrictivos,

Java es interpretado
El intrprete Java puede ejecutar directamente el cdigo objeto. Enlazar (linkar) un programa, normalmente, consume menos recursos que compilarlo, por lo que los desarrolladores con Java pasarn ms tiempo desarrollando y menos esperando. No obstante, el compilador actual del JDK (Java Development Kit) es bastante lento. Por ahora, que todava no hay compiladores especficos de Java para las diversas plataformas, Java es ms lento que otros lenguajes de programacin, como C++, ya que debe ser interpretado y no ejecutado como sucede en cualquier programa tradicional. Se dice que Java es de 10 a 30 veces ms lento que C, y que tampoco existen en Java proyectos de gran envergadura como en otros lenguajes. Lo que hay que dejar claro en todo esto, es que primero habra que decidir hasta que punto Java, un lenguaje en pleno desarrollo y todava sin definicin definitiva, est maduro corno lenguaje de programacin para ser comparado con otros; como por ejemplo con Smalltalk, que lleva ms de 20 aos. La verdad es que Java para conseguir ser un lenguaje independiente del sistema operativo y del procesador que incorpore la mquina utilizada, es tanto interpretado como compilado. Y esto no es ningn contrasentido, el cdigo fuente escrito con cualquier editor se compila generando el byte code. Este cdigo intermedio es de muy bajo nivel, pero sin alcanzar las instrucciones mquina propias de cada plataforma. El byte code corresponde al 80% de las instrucciones de la aplicacin. Ese mismo cdigo es el que se puede ejecutar sobre cualquier plataforma. Para ello hace falta el run time, que s es completamente dependiente de la mquina y del sistema operativo, que interpreta dinmicamente el byte code y aade el 20% de instrucciones que faltaban para su ejecucin. Con este sistema es fcil crear aplicaciones multiplataforma, pero para ejecutarlas es necesario que exista el run time correspondiente al sistema operativo utilizado.

Java es multithreaded
Al ser multithreaded (multi-hilo), Java permite muchas actividades simultneas en un programa. Los threads, son bsicamente pequeos procesos o piezas independientes de un gran proceso. Al estar los threads incluidos en el lenguaje, son ms fciles de usar y ms robustos que las sus implementaciones en C o C++. El beneficio de ser miltithreaded consiste en un mejor rendimiento interactivo y mejor

4 de 17

16/10/2012 20:04

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

comportamiento en tiempo real. Aunque el comportamiento en tiempo real est limitado a las capacidades del sistema operativo sobre el que corre, an supera a los entomos de flujo nico de programa (single-threaded) tanto en facilidad de desarrollo como en rendimiento. A continuacin profundizaremos un poco ms en el concepto de threads.

2. Conceptos Bsicos sobre Hilos


El multihilo soportado en Java gira alrededor del concepto de hilo. La cuestin es, qu es un hilo? De forma sencilla, un hilo es un nico flujo de ejecucin dentro de un proceso. Pero ser mejor comenzar desde el principio, un proceso es un programa ejecutndose dentro de su propio espacio de direcciones. lava es un sistema multiproceso, esto significa que soporta varios procesos corriendo a la vez dentro de sus propios espacios de direcciones. Estamos ms familiarizados con el trmino multitarea, el cual describe un escenario muy similar al multiproceso. Por ejemplo, consideremos la cantidad de aplicaciones que corren a la vez dentro de un mismo entorno grfico. Mientras escribo esto, est corriendo Microsoft Word adems de Internet Explorer, Windows Explorer, CD Player y el Volumen Control. Estas aplicaciones son todas procesos ejecutados dentro de Windows 98. De esta forma, se puede pensar que los procesos son anlogos a las aplicaciones o a programas aislados, pero cada proceso tiene asignado espacio propio de ejecucin dentro del sistema. Un hilo es una secuencia de cdigo en ejecucin dentro del contexto de un proceso. Los hilos no pueden ejecutarse ellos solos; requieren la supervisin de un proceso padre para correr.Dentro de cada proceso hay varios hilos ejecutndose. Por ejemplo, Word puede tener un hilo en background chequeando automticamente la gramtica de lo que estoy escribiendo, mientras otro hilo puede estar salvando automticamente los cambios del documento en el que estoy trabajando. Como Word, cada aplicacin (proceso) puede correr varios hilos los cuales estn realizando diferentes tareas. Esto significa que los hilos estn siempre asociados con un proceso en particular. Los hilos a menudo son conocidos o llamados procesos ligeros. Un hilo, en efecto, es muy similar a un proceso pero con la diferencia de que un hilo siempre corre dentro del contexto de otro programa. Por el contrario, los procesos mantienen su propio espacio de direcciones y entorno de operaciones. Los hilos dependen de un programa padre en lo que se refiere a recursos de ejecucin Java es un lenguaje de programacin que incorpora hilos en el corazn del mismo lenguaje. Comnmente, los hilos son implementados a nivel de sistema, requiriendo una interfaz de programacin especfica separada del ncleo del lenguaje de programacin. Esto es lo que ocurre con CIC++ programando en Windows, porque se necesita usar la interfaz de programacin Win32 para desarrollar aplicaciones Windows multihilo. Java se presenta como ambos, como lenguaje y como sistema de tiempo de ejecucin (runtime), siendo posible integrar hilos dentro de ambos. El resultado final es que se pueden usar hilos Java como standard, en cualquier plataforma.

5 de 17

16/10/2012 20:04

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

3. Clases Relacionadas con los Hilos


El lenguaje de programacin Java proporciona soporte para hilos a travs de una simple interfaz y un conjunto de clases. La interfaz de Java y las clases que incluyen funcionalidades sobre hilos son las siguientes: Thread Runnable Object Thread

Thread
La clase Thread es la clase responsable de producir hilos funcionales para otras clases. Para aadir la funcionalidad de hilo a una clase simplemente se deriva la clase de Thread y se ignora el mtodo run. Es en este mtodo run donde el procesamiento de un hilo toma lugar, ya menudo se refieren a l como el cuerpo del hilo. La clase Thread tambin define los mtodos start y stop, los cuales te permiten comenzar y parar la ejecucin del hilo, adems de un gran nmero de mtodos tiles.

Runnable
Java no soporta herencia mltiple de forma directa, es decir, no se puede derivar una clase de varias clases padre. Esto nos plantea la duda sobre cmo podemos aadir la funcionalidad de Hilo a una clase que deriva de otra clase, siendo sta distinta de Thread. Para lograr esto se utiliza la interfaz- Runnable. La interfaz Runnable proporciona la capacidad de aadir la funcionalidad de un hio a una clase simplemente implementando la interfaz, en lugar de derivndola de la clase Thread. Las clases que implementan la interfaz Runnable proporcionan un mtodo run que es ejecutado por un objeto hilo asociado que es creado aparte. Esta es una herramienta muy til y a menudo es la nica salida que tenemos para incorporar multihilo dentro de las clases. Esta cuestin ser tratada ms ampliamente en el apartado de Creacin de hilos.

Object
Aunque, estrictamente hablando, no es una clase de apoyo a los hilos, la clase objeto proporciona unos cuantos mtodos cruciales dentro de la arquitectura multihilo de Java. Estos mtodos son wait, notify y notifyAll. El mtodo wait hace que el hilo de ejecucin espere en estado dormido hasta que se le notifique que contine. Del mismo modo, el mtodo notify informa a un hilo en espera de que contine con su ejecucin. El mtodo notifyAll es similar a notify excepto que se aplica a todos los hilos en espera. Estos tres mtodos solo pueden ser llamados desde un mtodo o bloque sincronizado (o bloque de sincronizacin).

4. Creacin de Hilos
En Java, los hilos comparten el mismo espacio de memoria. Incluso comparten gran parte del entorno de ejecucin, de modo que la creacin de nuevos hilos es mucho ms rpida que la creacin de nuevos procesos. La ventaja que proporcionan los hilos

6 de 17

16/10/2012 20:04

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

es la capacidad de tener ms de un camino de ejecucin en un mismo programa. As, con un nico proceso, ejecutndose una J VM (Java Virtual Machine), habr siempre ms de un hilo, cada uno con su propio camino de ejecucin. En cuanto al proceso de creacin de hilos, son dos los mecanismos que nos permiten llevarlo a cabo en Java: implementando la interfaz Runnable, o extendiendo la clase Thread, esto es, creando una subclase de esta clase. En ambos casos, se deber definir un mtodo run que ser el incluya las instrucciones que se ejecutarn en el thread y se pueden definir prioridades aunque no se puede confiar en que la maquina virtual escoja para ejecutar,- siempre, el de mayor prioridad por lo que no se pueden utilizar para basar en ellas el scheduler e un sistema de tiempo real Creacin de un hilo: la clase Thread
class Repeticion extends Thread { prvate int repeticiones; private String mensaje; Repeticion (String msg, int n) { mensaje = msg; repeticiones = n; } public void run () { for (int i = 1; i <= repeticiones; i++) System.out.println (mensaje + " " + i); } public static void main (String args[]) { Repeticion r1 = new Repeticion ("Rojo", 5); Repeticion r2 = new Repeticion ("Azul", 80); rl.start (); r2.start (); }

En el caso de crear un hilo extendiendo la clase Thread, se pueden heredar los mtodos y variables de la clase padre. Si es as, una misma subclase solamente puede extender o derivar una vez de la clase padre Thread. Esta limitacin de Java puede ser superada a travs de la implementacin de Runnable. Creacin de un hilo: la interfaz Runnable
class Repeticion2 implements Runnable { private int repeticiones; private String mensaje; Repeticion2 (String msg, int n) { mensaje = msg; repeticiones = n; } public void run () { for (int i = 1; i <= repeticiones; i++) System.out.println (mensaje + " " + i); } } public static void main (String args[]) { Repeticion rl = new Repeticion ("Rojo", 5); Thread r2 = new Thread (new Repeticion2 ("Azul", 80)); r1. start (); r2. start ();

7 de 17

16/10/2012 20:04

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

5. Estado y Control de Hilos


5.a. Estados de un Hilo
El comportamiento de un hilo depende del estado en que se encuentre, este estado define su modo de operacin actual, por ejemplo, si esta corriendo o no. A continuacin proporcionamos la relacin de estados en los que puede estar un hilo Java. New Runnable Blocked Dead

New
Un hilo esta en el estado new la primera vez que se crea y hasta que el mtodo start es llamado. Los hilos en estado new ya han sido inicializados y estn listos para empezar a trabajar, pero an no han sido notificados para que empiecen a realizar su trabajo.

Runnable
Cuando se llama al mtodo start de un hilo nuevo, el mtodo run es invocado y el hilo entra en el estado runnable. Este estado podra llamarse "running" porque la ejecucin del mtodo run significa que el hilo esta corriendo. Sin embargo, debemos tener en cuenta la prioridad de los hilos. Aunque cada hilo est corriendo desde el punto de vista del usuario, en realidad todos los hilos, excepto el que en estos momentos esta utilizando la CPU, estn en el estado runnable (ejecutables, listos para correr) en cualquier momento dado. Uno puede pensar conceptualmente en el estado runnable como si fuera el estado "numing", slo tenemos que recordar que todos los hilos tienen que compartir los recursos del sistema.

Bloked
El estado not running se aplica a todos los hilos que estn parados por alguna razn. Cuando un hilo est en este estado, est listo para ser usado y es capaz de volver al estado runnable en un momento dado. Los hilos pueden pasar al estado not running a travs de varias vas. A continuacin se citan diferentes eventos que pueden hacer que un hilo est parado de modo temporal. El El El El mtodo suspend ha sido llamado mtodo sleep ha sido llamado mtodo wait ha sido llamado hilo esta bloqueado por YO

8 de 17

16/10/2012 20:04

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

Para cada una de estas acciones que implica que el hilo pase al estado not running hay una forma para hacer que el hilo vuelva a correr. A continuacin presentamos la lista de eventos correspondientes que pueden hacer que el hilo pase al estado runnable. ..SI un hilo est suspendido, la invocacin del mtodo resume ..Si un hilo est durmiendo, pasarn el nmero de milisegundos que se ha especificado que debe dormir ., Si un hilo est esperando, la llamada a notify o notifyAll por parte del objeto por el que espera Si un hilo est bloqueado por UO, la finalizacin de la operacin 1/O en cuestin

Dead
Un hilo entra en estado dead cuando ya no es un objeto necesario. Los hilos en estado dead no pueden ser resucitados y ejecutados de nuevo. Un hilo puede entrar en estado dead a travs de dos vas: ..El mtodo run termina su ejecucin. ..El mtodo stop es llamado. La primera opcin es el modo natural de que un hilo muera. Uno puede pensar en la muerte de un hilo cuando su mtodo run termina la ejecucin como una muerte por causas naturales. En contraste a esto, est la muerte de un hilo "por causa" de su mtodo stop. Una llamada al mtodo stop mata al hilo de modo asncrono. Aunque la segunda opcin suene un poco brusca, a menudo es muy til. Por ejemplo, es bastante comn que los applets maten sus hilos utilizando el mtodo stop cuando el propio mtodo stop del applet ha sido invocado. La razn de esto es que el mtodo stop del applet es llamado normalmente como respuesta al hecho de que el usuario ha abandonado la pgina web que contena el applet y no es adecuado dejar hilos de un applet corriendo cuando el applet no est activo, as que es deseable matar los hilos. En esta figura podemos ver grficamente los diferentes estados por los que pude

9 de 17

16/10/2012 20:04

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

pasar un hilo:

5.b. Control de un hilo Atranque de un hilo


En el contexto de las aplicaciones, sabemos que es main la primera funcin que se invoca tras arrancar, y por tanto, lgicamente, es el lugar ms apropiado para crear y arrancar otros hilos. La lnea de cdigo:
tl = new TestTh( "Thread 1",(int)(Math.randomo*2000) );

Siendo TestTh una subclase de la clase Thread (o una clase que implemente la interfaz Runnable) crea un nuevo hilo. Los dos argumentos pasados, sin mayor relevancia, satisfarn el prototipo del constructor de la clase y se utilizarn para la inicializacin del objeto. Al tener control directo sobre los hilos, tenemos que arrancarlos explcitamente. Como ya se coment anteriormente, es la funcin miembro start la que nos permite hacerlo. En nuestro ejemplo sera:
tl.startO;

start, en realidad es un mtodo oculto en el hilo que llama al mtodo run.

Manipulacin de un hilo
Si todo fue bien en la creacin del objeto TestTh (tl), ste debera contener un hilo, una traza de ejecucin vlida, que controlaremos en el mtodo run del objeto. El cuerpo de esta funcin miembro viene a ser el cuerpo de un programa como ya los conocemos. Digamos que es la rutina main a nivel de hilo. Todo lo que queremos que haga el hilo debe estar dentro del mtodo run. Cuando finalice run, finalizar tambin el hilo que lo ejecutaba.

Suspensin de un Hilo
La funcin miembro suspend de la clase Thread permite tener un control sobre el hilo de modo que podamos desactivarlo, detener su actividad durante un intervalo de tiempo indeterminado, a diferencia del uso de la llamada al sistema sleep, que simplemente lleva al hilo a un estado de "dormido", y siempre durante un nmero de milisegundos concreto. Este mtodo puede resultar til si, construyendo un applet con un hilo de animacin, queremos permitir al usuario detener (que no finalizar) la animacin, hasta que ste decida reanudarla. Este mtodo no detiene la ejecucin permanentemente. El hilo es suspendido indefinidamente y para volver a activarlo de nuevo necesitamos realizar una invocacin a la funcin miembro resume. 12

Parada de un Hilo
Ya conocemos los mtodos de control de hilos que nos permiten arrancarlos, suspenderlos y reanudarlos. El ltimo elemento de control que se necesita sobre hilos

10 de 17

16/10/2012 20:04

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

es el mtodo stop, utilizado para terminar la ejecucin de un hilo de forma permanente: tl.stopo; Sealar que esta llamada no destruye el hilo, sino que detiene su ejecucin, y sta no puede reanudarse con el mtodo start. Cuando se desasignen las variables que se usan en el hilo, el objeto hilo (creado con new) quedar marcado para eliminarlo y el garbage collector (recolector de basura de Java) se encargar de liberar la memoria que utilizaba. Tiene sentido su utilidad, por ejemplo, en aplicaciones complejas que necesiten un control sobre cada uno de los hilos que se lancen. Por ltimo, un mtodo de control de hilos que nos permite comprobar si una instancia est viva (el hilo se ha arrancado y an no se ha detenido) o no (bien no se arranc; bien ya finaliz). Estamos hablando de la funcin miembro isAlive. tl.isAliveo; Devolver true en caso de que el hilo tl est vivo, es decir, ya se haya llamado a su mtodo run y no haya sido parado con un stop ni haya terminado el mtodo run en su ejecucin. En otro caso, lgicamente, devolver false.

6. Planificacin y Prioridad de Hilos


6.a. Planificacin (Scheduling)
Java tiene un Planificador (Scheduler), una lista de procesos, que muestra por pantalla todos los hilos que se estn ejecutando en todos los programas y decide cules deben ejecutarse y cules deben encontrarse preparados para su ejecucin. Hay dos caractersticas de los hilos que el planificador tiene en cuenta en este proceso de decisin. ..La prioridad del hilo (la ms importante). ..El indicador de demonio (que pasaremos a explicar en los siguientes apartados). La regla bsica del planificador es que si solamente hay hilos demonio ejecutndose, la Mquina Virtual Java (JVM) concluir. Los nuevos hilos heredan la prioridad y el indicador de demonio de los hilos que los han creado. El planificador determina qu hilos debern ejecutarse comprobando la prioridad de todos los hilos. Aquellos con prioridad ms alta dispondrn del procesador antes de los que tienen prioridad ms baja. El planificador puede seguir dos patrones, preventivo y no preventivo. Los planificadores preventivos proporcionan un segmento de tiempo a todos los hilos que estn corriendo en el sistema. El planificador decide cul ser el siguiente hilo a ejecutarse y llama a resume para darle vida durante un perodo fijo de tiempo. Cuando finaliza ese perodo de tiempo, se llama a su mtodo suspend y el siguiente hilo en la lista de procesos ser relanzado mediante su mtodo resume. Los planificadores no preventivos, en cambio, deciden qu hilo debe correr y lo ejecutan hasta que concluye. El hilo tiene control total sobre el sistema mientras est en ejecucin. El mtodo yield es un mecanismo que permite a un hilo forzar al planificador para que comience la ejecucin de otro hilo que est esperando. Dependiendo del sistema en que est corriendo Java, el planificador ser preventivo o

11 de 17

16/10/2012 20:04

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

no preventivo. El planificador de hilos no est especificado tan rigurosamente como el resto de clases en Java, y en este asunto hay, sin duda, diferencias de un sistema a otro. Por ejemplo, la versin del JDK 1.0.2 de Solafs es una versin no preventiva, a diferencia del planificador de Win32, que s lo es. [Esto es exactamente lo opuesto a lo que nos esperbamos.] Un planificador no preventivo no interrumpir un hilo en ejecucin, de forma muy parecida al comportamiento de Windows 3.1. El planificador de hilos Java de Win32 s interrumpir los hilos en ejecucin, dando lugar a una planificacin ms fiable. Por ejemplo, si se arrancan dos hilos con grandes bucles de ejecucin bajo un sistema Solaris, el hilo que arranc antes completar su tarea antes de que el otro consiga arrancar. Pero en Windows95 o NT, el segundo hilo s consigue turno de ejecucin.

6.b. Prioridad
Cada hilo tiene una prioridad, que no es ms que un valor entero entre 1 y 10, de modo que cuanto mayor el valor, mayor es la prioridad. El planificador determina el hilo que debe ejecutarse en funcin de la prioridad asignad, a cada uno de ellos. Cuando se crea un hilo en Java, ste hereda la prioridad de su padre, el hilo que lo ha creado. A partir de aqu se le puede modificar su prioridad en cualquier momento utilizando el mtodo setPriority . Las prioridades de un hilo varan en un rango de entero: comprendido entre MIN_PRIORITY y MAX_PRIORITY (anbas definidas en la clase Thread) El entero ms alto designar la prioridad ms alta y el ms bajo, como es de esperar, la menor Se ejecutar primero el hilo de prioridad superior, el llamado "Ejecutables", y slo cuando ste para, abandona o se convierte en "No Ejecutable", comienza la ejecucin de en hilo de prioridad inferior. Si dos hilos tienen la misma prioridad, el programador elige uno de ello! en alguna forma de competicin. El hilo seleccionado se ejecutar hasta que: ..Un hilo comprioridad mayor pase a ser "Ejecutable". * En sistemas que soportan tiempo-compartido, termina su tiempo. ..Abandone, o termine su mtodo run.
12 de 17 16/10/2012 20:04

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

Luego, un segundo hilo puede ejecutarse, y as continuamente hasta que el intrprete abandone. El algoritmo del sistema de ejecucin de hilos que sigue Java es de tipo preventivo. S en un momento dado un hilo que tiene una prioridad mayor a cualquier otro hilo que se est; ejecutando pasa a ser "Ejecutable", entonces el sistema elige a este nuevo hilo.

7. Sincronizacin
El problema de la sincronizacin de hilos tiene lugar cuando varios hilos intentan acceder al mismo recurso o dato. A la hora de acceder a datos comunes, los hilos necesitan establecer cierto orden, por ejemplo en el caso del productor consumidor. Para asegurarse de que hilos concurrentes no se estorban y operan correctamente con datos (o recursos) compartidos, un sistema estable previene la inanicin y el punto muerto o interbloqueo. La inanicin tiene lugar cuando uno o ms hilos estn bloqueados al intentar conseguir acceso a un recurso compartido de ocurrencias limitadas. El interbloqueo es la ltima fase de la inanicin; ocurre cuando uno o ms hilos estn esperando una condicin que no puede ser satisfecha. Esto ocurre muy frecuentemente cuando dos o ms hilos estn esperando a que el otro u otros se desbloquee, respectivamente. A continuacin se presenta un ejemplo, el problema del Productor/Consumidor, con la intencin de explicar de una forma ms prctica el concepto y las situciones de sincronizacin de hilos.

7.a. Ejemplo: problema del productor-consumidor


El productor genera un entero entre 0 y 9 (inclusive), lo almacena en un objeto "CubbyHole", e imprime el nmero generado. Para hacer ms interesante el problema de la sincronizacin, el productor duerme durante un tiempo aleatorio entre 0 y 100 milisegundos antes de repetir el ciclo de generacin de nmeros.
class Productor extends Thread { private CubbyHole cubbyhole; private int numero; public Productor(CubbyHole c, int numero) { cubbyhole = c; this.numero = numero; } public void run() { for (int i = 0; i < 10; i++) { cubbyhole.put(i); System.out.println("Productor#"+this.numero+"pone:"+i); try { sleep((int)(Math.randomo * 100)); } catch (InterruptedException e) { } } } }

El consumidor, por su parte, est "hambriento", consume todos los enteros de CubbyHole (exactamente el mismo objeto en que el productor puso los enteros en

13 de 17

16/10/2012 20:04

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

primer lugar) tan pronto como estn disponibles. 16


class Consumidor extends Thread prvate CubbyHole cubbyhole; private int numero; public Consumidor(CubbyHole c, int numero) { cubbyhole = c; this.numero = numero; } public void runo { int value = 0; for (int i = 0; i < 10; i++) { value = cubbyhole.geto; System.out.println("Consumidor#"+this.numero+"obtiene: "+value); } }

En este ejemplo, el Productor y el Consumidor comparten datos a travs de un objeto CubbyHole comn. Observar que ninguno de los dos hace ningn tipo de esfuerzo para asegurarse de que el consumidor obtiene cada valor producido una y slo una vez. La sincronizacin entre estos dos hilos realmente ocurre a un nivel inferior, dentro de los mtodos geto y puto del objeto CubbyHole. Sin embargo, asumamos por un momento que estos dos hilos no estn sincronizados y veamos los problemas potenciales que podra provocar esta situacin. Un problema sera el que se dara cuando el Productor fuera ms rpido que el Consumidor y generara dos nmeros antes de que el Consumidor tuviera una posibilidad de consumir el primer nmero. As el Consumidor se saltara un nmero. Parte de la salida se podra parecer a esto.
Consumidor #1 obtiene: 3 Productor #1 pone: 4 Productor #1 pone: 5 Consumidor #1 obtiene: 5

Otro problema podra aparecer si el consumidor fuera ms rpido que el productor y consumiera el mismo valor dos o ms veces. En esta situacin el Consumidor imprimir el mismo valor dos veces y podra producir una salida como esta.
Productor #1 pone: 4 Consumidor #1 obtiene: 4 Consumidor #1 obtiene: 4 Productor #1 pone: 5

De cualquier forma, el resultado es errneo. Se quiere que el consumidor obtenga cada entero producido por el productor y slo una vez. Los problemas como los descritos anteriormente, se llaman "condiciones de carrera". Se alcanzan cuando varios hilos ejecutados asncronamente intentan acceder a un mismo objeto al mismo tiempo y obtienen resultados errneos. Para prevenir estas condiciones en nuestro ejemplo Productor/Consumidor, el almacenamiento de un nuevo entero en CubbyHole por el Productor debe estar sincronizado con la recuperacin del entero por parte del Consumidor. El Consumidor debe consumir cada entero exactamente una vez. El programa productor-consumidor utiliza dos mecanismos diferentes para sincronizar los hilos Productor y Consumidor; los monitores, y los mtodos notifyo y wait.

7.b. Monitores

14 de 17

16/10/2012 20:04

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

A los objetos como CubbyHole, a los que acceden varios hilos, son llamados "condiciones variables". Una de las formas de controlar el acceso a estas condiciones variables y de, por tanto, sincronizar los hilos, son los monitores. Las secciones crticas son los segmentos del cdigo donde los hilos concurrentes acceden a las condiciones variables. Estas secciones, en Java, se marcan normalmente con la palabra reservada synchronized:
Synchronized int MiMetodoo;

Generalmente, las secciones crticas en los programas de Java son los mtodos. Sin embargo el uso indiscriminado de synchronized viola los fundamentos de la programacin objetuaL por lo que es mejor utilizar synelironized slo a nivel de mtodos. Java asocia un solo monitor a cada objeto que tiene un mtodo sincronizado. En el ejemplo anterior del productorconstm-iidor tiene dos mtodos de sincronizacin: puto, que cambia el valor de Obby~o y geto, para recuperar el valor actual. Este sera el cdigo fuente del objeto (lubhpdlohn utilizando las tcnicas de sincronizacin nuevas:
class CubbyHole { prvate nt contents; private boolean avalable = false; public synchronized int get() { whle (avalable == false) { try { wait(); } catch (InterruptedException e) { } } available = false; notify(); return contents; } public synchronized void put(int value) { while (available == true) { try { wait(); } catch (InterruptedExcepton e) { } contents value; available true; notify(); } }

La variable contents tiene el valor actual de CubbyHole y available indica si se puede recuperar o no el valor. Cuando available es verdadero, el productor an no ha acabado de producir. CubbyHole tiene dos mtodos de sincronizacin, y Java proporciona un solo monitor para cada ejemplar de CubbyHole (incluyendo el compartido por el Productor y el Consumidor). Siempre que el control entra en un mtodo sincronizado, el hilo que ha llamado al mtodo adquiere el monitor del objeto al cual pertenece el mtodo. Otros hilos no pueden llamar a un mtalo sincronizado del mismo objeto mientras el monitor no sea liberado. Cuando el Productor invoca el mtodo puto de CubbyHole, adquiere el monitor del objeto CubbyHole y por lo tanto el Consumidor no podr llamar a geto de CubbyHole y se quedar bloquedo (existe un mtodo, waito, que libera temporalmente el monitor). De igual forma sucede cuando el Consumidor invoca geto.

15 de 17

16/10/2012 20:04

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

public synchronized void put(int value) { // El productor adquiere el monitor while (available == true) { try { wait(); } catch (InterruptedException e) { contents = value; available = true; notify(); // lo notifica al Productor // El productor libera el monitor } public synchronized int get() { // El consumidor adquiere el monitor while (available == false) { try { wait(); // espera que el Productor invoque a notify() } catch (InterruptedException e) { } available = false; notify(); return contents; // el Consumidor libera el monitor }

8. Hilos Demonio (Daemon)


Un proceso demonio es un proceso que debe ejecutarse continuamente en modo background (en segundo plano), y generalmente se disea para responder a peticiones de otros procesos a travs de la red. La palabra "daemon" (proveniente de la palabra griega "ghost') es propia de UNIR, pero no se utiliza de este mismo modo en Windows. En Windows NT, los demonios se denominan "servicios". Cuando los servicios atienden peticiones, se conocen como la parte "Servidor" de una arquitectura Cliente/Servidor. Los hilos demonio tambin se llaman servicios, porque se ejecutan, normalmente, con prioridad baja y proporcionan un servicio bsico a un programa o programas cuando la actividad de la mquina es reducida. Un ejemplo de hilo demonio que est ejecutndose continuamente es el recolector de basura (garbage conector). Este hilo, proporcionado por la Mquina Virtual Java, comprueba las variables de los programas a las que no se accede nunca y libera estos recursos; devolvindolos al sistema. Un hilo puede fijar su indicador de demonio pasando un valor trae al mtodo setDaemono. Si se pasa false a este mtodo, el hilo ser devuelto por el sistema como un hilo de usuario. No obstante, esto ltimo debe realizarse antes de que se arranque el hilo con el mtodo startO.

9. Conclusiones
Se pueden usar hilos Java como standard, sin tener en cuenta la plataforma en la que vayan a ejecurtarse. La clase Thread es la clase responsable de producir hilos funcionales para otras clases. La interfaz Runnable proporciona la capacidad de aadir la funcionalidad de un hilo a una clase en lugar de derivndola de la clase Tbread.

16 de 17

16/10/2012 20:04

Programacin Concurrente con Java

http://equis.umh.es/alex-bia/Teaching/PC/material/programacion-concu...

Para arrancar un hilo se llama a su mtodo start el cual invoca al mtodo run del propio hilo. Todo la tarea del hilo debe estar dentro del mtodo run. Para terminar la ejecucin de un hilo de forma permanente se utiliza su mtodo stop. La clase ThreadGroup es la implementacin del concepto de grupo de hilos en Java. Java tiene un Planificador (Scheduler); el cual decide que hilos deben ejecutarse y cuales encontrarse preparados para su ejecucin. Cada hilo tiene una prioridad, que no es ms que un valor entero entre 1 y 10, de modo que cuanto mayor el valor, mayor es la prioridad.

Bibliografa
[1] Bruce Eckel " Thinking in JAVA " [2] David Arnow ; Gerald Weiss " Introduccion a la programacin con Java"

Referencias
[3] http://java.sun.com/docs/books/tutoriaVessential/threads [4] http://java.sun.comldocs/books/tutorial/nativel.l/implementinR/svnc.html [5] http://java.sun.com/applets/ [6] http://www.usenix.org/publications/java/usingjava3.html [7] http://java.sun.com/produets/jdk/1.2/docs/api/java/lang/Thread.html [8] http://java.sun.com/products/jdk/1.2/docs/api/java/lang/Runnable.html [9] http://java.sun.com/products/jdk/1.2/docs/ajava/lang/Object.html

ltima actualizacin: 28 de marzo de 2004 abia@dlsi.ua.es

17 de 17

16/10/2012 20:04

Você também pode gostar