Tema 12 - Hilos en Java

download Tema 12 - Hilos en Java

of 24

Transcript of Tema 12 - Hilos en Java

  • 5/25/2018 Tema 12 - Hilos en Java

    1/24

    ITSON Manuel Domitsu Kono

    Tema 12

    Hilos en JavaProcesos e Hilos

    En la programacin concurrente, hay dos unidades bsicas de ejecucin: procesose hilos. En el lenguaje de programacin Java, la programacin concurrente estms relacionada con los hilos. Sin embargo, los procesos tambin sonimportantes.

    Un Procesoes un ambiente de ejecucin autocontenido. Por lo general tienerecursos de ejecucin completos y privados, en particular cada proceso tiene supropio espacio de memoria.

    A veces se ve a los procesos como sinnimo de programas o aplicaciones. Sinembargo, una aplicacin puede ser un conjunto de procesos cooperativos. Parafacilitar la comunicacin entre procesos, la mayora de los sistemas operativossoportan recursos de Comunicacin entre Procesos, IPC, como tubos y sockets.IPC no slo se usa para comunicar procesos en un solo sistema sino procesos endiferentes sistemas.

    Un Hilo, llamado a veces proceso ligero, provee tambin un ambiente deejecucin. Pero crear un nuevo hilo requiere de menos recursos que crear unnuevo proceso.

    Los hilos existen dentro de los procesos cada proceso tiene al menos un hilo. Unproceso con un solo hilo tiene las siguientes propiedades:

    El proceso empieza su ejecucin en un punto bien conocido. En losprogramas como C, C++ o Java el proceso empieza su ejecucin en la

    primera sentencia del mtodo mai n( ) . La ejecucin de las sentencias sigue una secuencia predefinida

    completamente ordenada para un conjunto de entradas. Durante la ejecucin, el proceso tiene acceso a ciertos datos. En Java hay

    tres tipos de datos a los que un proceso puede acceder: variables localesque se encuentran en la pila del hilo. Variables de instancia que se accesanmediante referencias y variables estticas que se acceden mediante claseso referencias a objetos.

  • 5/25/2018 Tema 12 - Hilos en Java

    2/24

    430 Hilos en Java

    ITSON Manuel Domitsu Kono

    En la figura 11.1 se ilustra un ejemplo de un sistema multitarea, en el cual hay

    varias aplicaciones en ejecucin. Cada uno de ellos con un solo hilo de ejecucin.

    En este caso tenemos varios procesos ejecutndose simultneamente.

    Figura 12.1

    Aunque para el usuario, los procesos parecen estar ejecutndosesimultneamente, esto solo puede ocurrir en un sistema con varios procesadoreso con un procesador con varios ncleos de ejecucin. En el caso de un sistemacon un solo procesador mononcleo, la apariencia de ejecucin simultnea selogra compartiendo el procesador entre los diferentes procesos asignndole acada uno de ellos una ranura de tiempo y cambiando a ejecutar otro procesocuando el tiempo de la ranura se ha agotado.

    En un sistema multitarea que soporta multihilos, los hilos comparten los recursosde un proceso, incluyendo la memoria y los archivos abiertos. Esto hace lacomunicacin eficiente pero potencialmente problemtica. En este caso cada

    proceso puede tener uno o ms hilos. Los diferentes procesos y sus hilo puedenejecutarse simultneamente en forma real o aparente, dependiendo del nmero deprocesadores o ncleos.

    En un proceso, los hilos mltiples tienen las siguientes propiedades:

    Cada hilo empieza su ejecucin en un punto bien conocido. Para alguno de

    esos hilos ese punto es la primera sentencia del mtodo mai n( ) . Para elresto de los hilos, el programador decide ese punto al codificar el hilo.

    Cada hilo ejecuta su cdigo desde su punto inicial en una forma ordenada ypredefinida para un conjunto de entradas.

    Cada hilo ejecuta su cdigo independientemente de los otros hilos en elprograma. Si se requiere existen mecanismos para que los hilos cooperenentre s.

    Los hilos aparentar ejecutar con cierto grado de simultaneidad.

    Los hilos tienen acceso a varios tipos de datos. Cada hilo tiene sus propiasvariables locales. Los hilos pueden compartir las variables de instancia. Loshilos comparten en forma automtica a las variables estticas.

  • 5/25/2018 Tema 12 - Hilos en Java

    3/24

    Tema 12 Hilos en Java 431

    ITSON Manuel Domitsu Kono

    En la figura 12.2 se ilustra un ejemplo de un sistema multitarea, en el cual hay

    varias aplicaciones en ejecucin. Cada uno de ellos puede tener varios hilos de

    ejecucin. En este caso, uno de esos procesos es la mquina virtual de java.

    Figura 12.2

    La ejecucin multihilo es una caracterstica esencial de la plataforma de Java.Cada aplicacin tiene al menos un hilo o varias si se cuentan los hilos del sistemaque administran la memoria y el manejo de las seales. Pero desde el punto devista del programador se empieza con un hilo, llamado el hilo principal. Este hilotiene la habilidad de crear hilos adicionales como se ver ms adelante.

    La API de Java para Hilos

    Para comprender el funcionamiento de un programa multihilo veamos primero unprograma con un solo hilo de ejecucin. Considere el el siguiente programaformado por dos clases:

    Hilo.javapubl i c cl ass Hi l o {

    publ i c voi d r un( ) {f or ( i nt i = 0; i < 100; i ++) {

    Syst em. out . pr i nt l n( i + ": Hol a") ;}

    }}

  • 5/25/2018 Tema 12 - Hilos en Java

    4/24

    432 Hilos en Java

    ITSON Manuel Domitsu Kono

    Prueba.java

    publ i c cl ass Pr ueba {publ i c st at i c voi d mai n( St r i ng[ ] ar gs) {

    Hi l o hi l o = new Hi l o( ) ;

    hi l o. run( ) ;

    }}

    En la figura 12.3 se muestra el comportamiento del programa con el tiempo. Eneste caso como slo hay un hilo de ejecucin las sentencias se ejecutan unadespus de la otra. No hay concurrencia.

    Figura 12.3

    Para hacer que el mtodo run() ejecute en paralelo con el mtodo mai n( ) yotros mtodos de la clase Prueba, hay que modificar la clase Hilo para que seaejecutado por un nuevo hilo. Para ello nuestra clase Hilo deber heredar de la

    claseThread. Como se muestra en el siguiente cdigo:

    Hilo.javapubl i c cl ass Hi l o ext ends Thr ead {

    publ i c voi d r un( ) {f or ( i nt i = 0; i < 100; i ++) {

    Syst em. out . pr i nt l n( I + ": Hol a") ;}

    }

    }

    Tambin debemos modificar a la clase que invoca a la clase Hi l opara que enlugar de invocar a su mtodo run() invoque a su mtodo s ta r t ( ) .

    Prueba.java

  • 5/25/2018 Tema 12 - Hilos en Java

    5/24

    Tema 12 Hilos en Java 433

    ITSON Manuel Domitsu Kono

    publ i c cl ass Pr ueba {publ i c st at i c voi d mai n( St r i ng[ ] ar gs) {

    Hi l o hi l o = new Hi l o( ) ;

    hi l o. st ar t ( ) ;}

    }

    El mtodo s ta r t ( ) es quien crea otro hilo de ejecucin. Este hilo, despus de unproceso de inicializacin invoca al mtodo run() . Este mismo hilo, cuando elmtodo run() completa se encarga de os detalles de terminacin del hilo. Elmtodo s ta r t ( ) del hilo original regresa inmediatamente, por lo que el mtodorun() ejecutar en el nuevo hilo al mismo tiempo que el mtodo s ta r t ( ) regresa en el primer hilo como se muestra en la figura 12.4.

    Figura 12.4

    La claseThreadforma parte de la API de Java para hilos. Parte de esa API se

    muestra en la figura 12.5.

    Tabla 12.1 Atributos de la Clase Threadpubl i c s tat i c f i nal i nt MAX_PRIORITY

    La mxima prioridad que puede tener un hilo

    publ i c s tat i c f i nal i nt MIN_PRIORITY

    La mnima prioridad que puede tener un hilopubl i c st at i c f i nal i nt NORM_PRIORITY

    La prioridad por ausencia, que puede tener un hilo

  • 5/25/2018 Tema 12 - Hilos en Java

    6/24

    434 Hilos en Java

    ITSON Manuel Domitsu Kono

    Figura 12.4

    Tabla 12.2 Mtodos de la Clase Thread.publ i c Thr ead( )publ i c Thr ead( Runnabl e t arget )

    publ i c Thr ead( Runnabl e t arget , St r i ng name)publ i c Thr ead( St r i ng name)

    Crean nuevos hilos. El parmetro target denota el objeto del cual se ejecuta el mtodo run() .El

    valor por omisin es nul l . El parmetro nameestablece el nombre del nuevo hilo. El valor

    prestablecido es Thr ead- n, donde nes un entero consecutivo.

    publ i c voi d start( )

    Hace que este hilo inicie su ejecucin; La mquina virtual de Java llama al mtodo run() de estehilo. Como resultado hay dos hilos ejecutndose concurrentemente. El hilo actual (que regresa de

    la llamada al mtodo s ta r t ( ) y el otro hilo (que ejecuta su mtodo run() ).

    Es ilegal iniciar un hilo ms de una vez. En particular un hilo no puede reiniciarse una vez que

    completa su ejecucin.

    Lanza:

    I l l egal Thr eadSt at eExcept i on Si el hilo ya ha sido iniciado.publ i c voi d run( )

    Si este hilo fue construido usando un objeto Runnabl ediferente, entonces se invoca al mtodorun() del objeto. De otra forma, el mtodo no hace nada y regresa.

  • 5/25/2018 Tema 12 - Hilos en Java

    7/24

    Tema 12 Hilos en Java 435

    ITSON Manuel Domitsu Kono

    Hilos Usando la Interfaz Runnable

    Hay ocasiones en que crear un hilo heredando de la claseThreadno esconveniente. Por ejemplo, si la clase que deseamos que sea un hilo, es una

    subclase, no podemos hacer que herede de la claseThreadya que una claseslo puede heredar de una clase. En estos casos, en vez de hacer que la clase

    herede de la claseThreadharemos que la clase implemente la interfazRunnabl e, como se muestra en el siguiente cdigo:

    HiloRunnable.javapubl i c cl ass Hi l oRunnabl e i mpl ement s Runnabl e {

    publ i c voi d r un( ) {f or ( i nt i = 0; i < 100; i ++) {

    Syst em. out . pr i nt l n( i + ": Hol a desde l a cl ase Hi l o") ;}

    }}

    Una clase que implemente la interfaz debe implementar el mtodo run(). Sinembargo para crear un nuevo hilo no es suficiente con crear una instancia de la

    clase que implementa la interfaz Runnabl ee invocar a su mtodo s t a r t ( ) yaque la clase no hereda de la claseThready no tiene el mtodo s ta r t ( ) . Enlugar de ello crearemos un nuevo hilo y le pasaremos al constructor de la claseThreadla instancia de la clase que implementa la interfaz Runnabl e, como semuestra en el siguiente cdigo:

    PruebaHiloRunnable.java

    publ i c cl ass PruebaHi l oRunnabl e {publ i c st at i c voi d mai n( St r i ng[ ] ar gs) {

    Runnabl e hi l oRunnabl e = new Hi l o( ) ;Thread hi l o = new Thread(hi l oRunnabl e) ;

    hi l o. st ar t ( ) ;}

    }

    La razn para pasarle un objeto Runnabl eal constructor de la claseThreadespara que el hilo tenga acceso al mtodo run() del objeto Runnabl epara que lo

    ejecute. El mtodo s ta r t ( ) del hilo llama al mtodo run() de la claseThreadya que no fue sobrescrito, que a su vez llama al mtodo run() del objetoRunnabl eya que el mtodo run() por ausencia de la claseThreadtiene laforma:

    publ i c voi d r un( ) {i f ( t arget != nul l ) t arget . run( ) ;

    }

  • 5/25/2018 Tema 12 - Hilos en Java

    8/24

    436 Hilos en Java

    ITSON Manuel Domitsu Kono

    Donde target es el objeto Runnabl eque le pasamos al constructor del hilo. Asque el hilo empieza la ejecucin de su mtodo run() quien inmediatamente llama al

    mtodo run() del objeto Runnabl e.

    Suspender y Parar un Hilo

    La ejecucin de un hilo puede ser suspendida temporalmente, invocando a su mtodosleep(), tabla 12.3.

    Tabla 12.3 Mtodos de la Clase Thread. Cont.publ i c stat i c voi d sleep( l ong mi l l i s) t hr ows I nt er r upt edExcept i onpubl i c stat i c voi d sleep( l ong mi l l i s , i nt nanos)

    t hr ows I nt er r upt edExcept i on

    Hace que el hilo, actualmente en ejecucin se duerma (cese temporalmente su ejecucin) por elnmero de milisegundos (ms el nmero de nanosegundos, en el caso del segundo mtodo) dadopor el parmetro, sujeto a la precisin y exactitud de los temporalizadores y el programador

    tareas. El hilo no pierde la propiedad de ninguno de sus monitores.

    El valor del parmetro nanosdebe estar en el rango de 0 999999 nanosegundos.

    Lanza:

    I nt er r upt edExcept i on Si cualquier hilo ha interrumpido este hilo. El estadointerrumpido del hilo actual se limpia cuando se lanza esta excepcin.I l l egal Ar gument Except i on Si el valor de mi l l i ses negativo o el valor de nanosno est en el rango de 0 999999 nanosegundos.

    publ i c f i nal bool ean isAlive( )

    Checa si el hilo est vivo. Un hilo est vivo si ha sido iniciado y no ha muerto.

    El siguiente cdigo muestra el uso del mtodo sl eep( ) de la claseThreadparaimplementar un hilo que ejecuta una tarea peridicamente. En este ejemplo, elmtodo suspende la ejecucin del hilo por 1000 ms por lo que el ciclo despliega elmensaje aproximadamente cada 1 s mientras se repita el ciclo.

    Este cdigo tambin ilustra la forma de parar un hilo. Para parar un hilo hay que

    hacer que su mtodo run() termine su ejecucin y regrese. Para lograr eso en laclase principal hacemos que la variable vivo tome el valor de falso, lo que har que

    el ciclo termine y termine tambin el mtodo run() . Tambin en la clase principalle asignamos a la referencia al hilo, t empor i zador , el valor de null para que el

    recolector de basura destruya al objeto y libere los recursos que el hilo tenaasignados.

    Temporizador.javapubl i c cl ass Tempor i zador ext ends Thr ead {

    publ i c vol at i l e bool ean vi vo;

    publ i c Tempori zador( ) {vi vo = t r ue;

  • 5/25/2018 Tema 12 - Hilos en Java

    9/24

    Tema 12 Hilos en Java 437

    ITSON Manuel Domitsu Kono

    }

    publ i c voi d r un( ) {

    whi l e ( vi vo) {try {

    Syst em. out . pr i nt l n( "Despi er t o") ;

    sl eep( 1000) ;} catch ( Except i on e) {}

    }}

    }

    PruebaTemporizador.javapubl i c cl ass PruebaTempor i zador {

    publ i c st at i c voi d mai n( St r i ng[ ] ar gs) {Tempor i zador t empor i zador = new Tempor i zador ( ) ;

    t empor i zador . st ar t ( ) ;

    try {Thread. sl eep( 10000) ;

    }cat ch( I nt er r upt edExcept i on i e) {

    Syst em. out . pr i nt l n( i e. get Message( ) ) ;}

    t empor i zador . vi vo = f al se;t empori zador = nul l ;

    }

    }

    El ciclo de Vida de un Hilo

    En la figura 12.5 muestra el ciclo de vida de un hilo. Hay un periodo de tiempo

    despus de que se invoca al mtodo s ta r t ( ) antes de que la mquina virtual deJava pueda arrancar al hilo. En forma similar, cuando un hilo regresa de sumtodo run(), hay un periodo de tiempo antes que la mquina virtual de Javapueda liberar los recursos ocupados por el hilo. Este atraso ocurre por que tomatiempo arrancar o terminar un hilo; luego hay un tiempo de transicin entre elestado de ejecucin y el estado de parado de un hilo como se muestra en la figura12.5.

  • 5/25/2018 Tema 12 - Hilos en Java

    10/24

    438 Hilos en Java

    ITSON Manuel Domitsu Kono

    Figura 12.5

    Para saber si un hilo ya ha arrancado o si ya terminado podemos llamar al mtodo

    i sAl i ve( ) . Por ejemplo, en el siguiente cdigo, nos aseguramos que el hilo yahaya terminado antes de liberar los recursos que se le hayan asignado:

    PruebaTemporizador.javapubl i c cl ass PruebaTempor i zador {

    publ i c st at i c voi d mai n( St r i ng[ ] ar gs) {Tempor i zador t empor i zador = new Tempor i zador ( ) ;

    t empor i zador . st ar t ( ) ;

    try {Thread. sl eep( 10000) ;

    }cat ch( I nt er r upt edExcept i on i e) {

    Syst em. out . pr i nt l n( i e. get Message( ) ) ;}

    t empor i zador . vi vo = f al se;whi l e (t empor i zador . i sAl i ve( ) ) {

    try {Thread. sl eep( 100) ;

    } cat ch ( I nt er r upt edExcept i on i e) {Syst em. out . pr i nt l n( i e. get Message( ) ) ;

    }}

    t empori zador = nul l ;}

    }

    Unin de Hilos

    En el ejemplo anterior usamos los mtodos i sAl i ve( ) y sl eep( ) de un hilopara esperar a que el hilo termine su ejecucin antes de liberar los recusos

  • 5/25/2018 Tema 12 - Hilos en Java

    11/24

    Tema 12 Hilos en Java 439

    ITSON Manuel Domitsu Kono

    asignados al hilo. Hay otros mtodos en la API de Java que son ms adecuadospara esta tarea. A este acto de esperar se le conoce como una unin de hilos. Nosestamos uniendo con el hilo creado previamente. Para unirnos con un hilopodemos usar el mtodoj oi n( ) , tabla 12.4.

    Tabla 12.4 Mtodos de la Clase Thread. Cont.publ i c f i nal voi d join( ) t hr ows I nt er r upt edExcept i on

    Espera a que este hilo muera.

    Lanza:

    I nt er r upt edExcept i on Si cualquier hilo ha interrumpido este hilo. El estadointerrumpido del hilo actual se limpia cuando se lanza esta excepcin.

    publ i c f i nal voi d join( l ong mi l l i s) t hr ows I nt er r upt edExcept i onpubl i c f i nal voi d join( l ong mi l l i s, i nt nanos) t hr ows I nt er r upt edExcept i onEspera a que este hilo muera cuando mucho el nmero de milisegundos (ms el nmero denanosegundos, en el caso del segundo mtodo) dado por el parmetro. En el primer mtodo, un

    valor del parmetro de 0 significa esperar por siempre.

    El valor del parmetro nanosdebe estar en el rango de 0 999999 nanosegundos.

    Lanza:I nt er r upt edExcept i on Si cualquier hilo ha interrumpido este hilo. El estadointerrumpidodel hilo actual se limpia cuando se lanza esta excepcin.I l l egal Ar gument Except i on Si el valor de mi l l i ses negativo o el valor de nanosno est en el rango de 0 999999 nanosegundos.

    El siguiente cdigo ilustra el uso del mtodoj oi n( ) para esperar que un hilotermine su ejecucin:

    PruebaTemporizador.javapubl i c cl ass PruebaTempor i zador {

    publ i c st at i c voi d mai n( St r i ng[ ] ar gs) {Tempor i zador t empor i zador = new Tempor i zador ( ) ;

    t empor i zador . st ar t ( ) ;

    try {Thread. sl eep( 10000) ;

    }cat ch( I nt er r upt edExcept i on i e) {

    Syst em. out . pr i nt l n( i e. get Message( ) ) ;

    }t empor i zador . vi vo = f al se;

    try {t empor i zador . j oi n( ) ;

    } cat ch ( I nt er r upt edExcept i on i e) {Syst em. out . pr i nt l n( i e. get Message( ) ) ;

    }

  • 5/25/2018 Tema 12 - Hilos en Java

    12/24

    440 Hilos en Java

    ITSON Manuel Domitsu Kono

    t empori zador = nul l ;}

    }

    Tabla 12.5 Otros Mtodos de la Clase Thread. Cont.publ i c f i nal St r i ng getName( )

    Regresa el nombre de este hilo.publ i c f i nal voi d setName( St r i ng name)

    Cambia el nombre de este hilo por el valor del parmetro.

    Lanza:

    Secur i t yExcept i on Si el hilo actual no puede modificar el nombre de este hilo.publ i c stat i c Thr ead currentThread( )

    Regresa una referencia al hilo actual en ejecucin.publ i c stat i c i nt enumerate(Thread[] tarray)

    Copia en el arreglo del parmetro todos los hilos activos.

    Regresa:El nmero de hilos colocados en el arreglo.

    Lanza:

    Secur i t yExcept i on Si el hilo actual no puede modificar el nombre de este hilo.publ i c stat i c i nt activeCount( )

    Regresa el nmero de hilos actives.publ i c voi d interrupt( )

    Interrumpe este hilo.

    Si este hilo est bloqueado en una invocacin de los mtodos wai t ( ) de la clase Obj ect o delos mtodosj oi n( ) o sl eep( ) de esta clase, entonces su estado interrumpidose limpia yrecibir una excepcin del tipo I nt er r upt edExcept i on. De otra manera el estado interrumpidose establecer.

    Lanza:

    Secur i t yExcept i on Si el hilo actual no puede modificar este hilo.publ i c stat i c bool ean interrupted( )

    Prueba si el hilo actual ha sido interrumpido. El mtodo limpia el estado interrumpidodel hilo. Enotras palabras, si este mtodo se llama dos veces en consecutivas, la segunda llamada, regresarfalso (a menos que el hilo actual sea interrumpido de nuevo, despus de que la primera llamada

    haya limpiado su estado interrumpidoy antes de que la segunda llamada lo inspeccione.publ i c bool ean isInterrupted( )Prueba si el hilo actual ha sido interrumpido. El mtodo no modifica el estado interrumpidodel hilo.publ i c f i nal i nt getPriority( )Regresa la prioridad de este hilo.

  • 5/25/2018 Tema 12 - Hilos en Java

    13/24

    Tema 12 Hilos en Java 441

    ITSON Manuel Domitsu Kono

    Tabla 12.5 Otros Mtodos de la Clase Thread. Cont.publ i c f i nal voi d setPriority( i nt newPri or i t y)

    Cambia la prioridad de este hilo.

    Lanza:I l l egal Ar gument Except i on Si la prioridad no est en el rango de MI N_PRI ORI TYa

    MAX_PRI ORI TY.

    Throws:

    I l l egal Ar gument Except i on- If the priority is not in the range MI N_PRI ORI TYto

    MAX_PRI ORI TY.Secur i t yExcept i on Si el hilo actual no puede modificar este hilo.

    publ i c stat i c voi d yield( )

    Hace que el hilo en ejecucin actualmente, haga una pausa temporal y permita que otro hiloejecute.

    Sincronizacin

    Al compartir datos entre varios hilos puede ocurrir una situacin llamadacondicin de carreraentre dos hilos intentando acceder al mismo dato a ms omenos al mismo tiempo. Para ilustrar el problema veamos el siguiente problema:

    Suponga que se desea implementar una aplicacin para un cajero automtico. Laprimera tarea es disear e implementar el caso de uso que permite a un usuarioretirar efectivo de un cajero. El primer intento de algoritmo puede ser:

    1. Verificar que el usuario tenga suficiente efectivo en su cuenta para cubrir elretiro. Si no lo tiene ir al paso 4.

    2. Restar la cantidad a retirar de la cuenta del usuario3. Entregar el dinero al usuario4. Imprimir el recibo del usuario.La implementacin del algoritmo podra ser la siguiente:

    publ i c cl ass Caj er oAut omat i co extends Caj er o {publ i c voi d r et i r ar( f l oat cant i dad) {

    Cuenta c = get Cuenta( ) ;

    i f ( c. deduci r( cant i dad) )

    ent r egar ( cant i dad) ;i mpr i mi r Reci bo( ) ;}

    Cuenta getCuenta( ) {. . .

    }

    voi d ent r agar ( f l oat cant i dad) {. . .

  • 5/25/2018 Tema 12 - Hilos en Java

    14/24

    442 Hilos en Java

    ITSON Manuel Domitsu Kono

    }

    voi d i mpr i mi r Reci bo( ) {. . .

    }}

    publ i c cl ass Cuent a {pr vate f l oat tot al ;

    publ i c bool ean deduci r ( f l oat t ) {i f ( t

  • 5/25/2018 Tema 12 - Hilos en Java

    15/24

    Tema 12 Hilos en Java 443

    ITSON Manuel Domitsu Kono

    publ i c cl ass Cuent a {pr vate f l oat tot al ;

    publ i c syncroni zedbool ean deduci r ( f l oat t ) {i f ( t

  • 5/25/2018 Tema 12 - Hilos en Java

    16/24

    444 Hilos en Java

    ITSON Manuel Domitsu Kono

    Declarar un mtodo como sincronizado es equivalente a:

    modificadorAcceso tipo nomMetodo(lista de parmetros) {

    syncronized(this) {

    declaraciones

    sentencias}

    }

    Esperar y Notif icar

    La clase Obj ect tiene los mtodos wai t ( ) ynot i f y( ) . Esos mtodos permitenque un hilo libere el candado en un momento arbitrario, y espere a que otro hilo selo regrese antes de continuar. Estas actividades deben ocurrir dentro de bloquessincronizados.

    Tabla 12.4 Mtodos de la Clase ObjectEmpleados con Hilos

    publ i c f i nal voi d notify( )

    Despierta un solo hilo que est esperando por el monitor de este objeto. Si hay varios hilosesperando por este objeto, uno de ellos es seleccionado para despertarse. La seleccin esarbitraria y ocurre a la discrecin de la implementacin. Un hilo espera por el monitor del objeto alllamar a alguno de sus mtodos wai t ( ) .

    El hilo despertado no podr proceder hasta que el hilo actual libere el candado sobre el objeto. Elhilo despertado competir con cualquier otro hilo que este compitiendo activamente parasincronizarse con este objeto; por ejemplo, el hilo despertado no tiene privilegios o desventajaspara ser el siguiente hilo en ponerle un candado al objeto.

    Este mtodo slo debe llamarlo un hilo que sea el dueo del monitor del objeto. Un hilo se vuelve

    el dueo del monitor del objeto en una de tres formas:

    Ejecutando una mtodo de instancia sincronizado del objeto.

    Ejecutando el cuerpo de una sentencia sincronizada que sincroniza en el objeto.

    En los objetos de tipo Class, ejecutando un mtodo esttico de la clase.

    Slo uno de los hilos a la vez puede ser el dueo del monitor del objeto.

    Lanza:I l l egal Moni t or St at eExcept i on Si el hilo actual no es el dueo del monitor delobjeto.

  • 5/25/2018 Tema 12 - Hilos en Java

    17/24

    Tema 12 Hilos en Java 445

    ITSON Manuel Domitsu Kono

    Tabla 12.4 Mtodos de la Clase ObjectEmpleados con Hilos. Cont.publ i c f i nal voi d notifyAll( )

    Despierta a todos los hilos que estn esperando por el monitor del objeto. Un hilo espera por el

    monitor del objeto al llamar a alguno de sus mtodos wai t ( ) .

    Los hilos despertados no podrn proceder hasta que el hilo actual libere el candado sobre elobjeto. Los hilos despertados competirn con cualquier otro hilo que este compitiendo activamentepara sincronizarse con este objeto; por ejemplo, el hilo despertado no tiene privilegios odesventajas para ser el siguiente hilo en ponerle un candado al objeto.

    Este mtodo slo debe llamarlo un hilo que sea el dueo del monitor del objeto.

    Lanza:I l l egal Moni t or St at eExcept i on Si el hilo actual no es el dueo del monitor delobjeto.

    publ i c f i nal voi d wait( l ong t i meout ) t hr ows I nt er r upt edExcept i on

    Hace que el hilo actual espere hasta que otro hilo invoque al mtodo not i f y( ) o al mtodo

    not i f yAl l ( ) de este objeto, o la cantidad de milisegundos especificada por el parmetro hayatranscurrido.

    El hilo actual debe poseer el monitor de este objeto.

    Este mtodo hace que el hilo actual se coloque en el estado de espera para este objeto y luegolibere cualquier derecho de sincronizacin en este objeto. El hilo deja de estar disponible para elplanificador de procesos y permanece dormido hasta que alguna de estas cuatro cosas suceden:

    Algn otro hilo invoca al mtodo not i f y( ) para este objeto y el hilo es seleccionadoarbitrariamente para ser el hilo a despertar.

    Algn otro hilo invoca al mtodo not i f yAl l ( ) para este objeto. Algn otro hilo interrumpe al hilo.

    El tiempo en milisegundos especificado por el parmetro ha transcurrido (ms o menos).Si t i meout es cero, el hilo espera hasta ser notificado.

    El hilo es removido del estado de espera para este objeto y queda disponible para el planificadorde procesos. Luego compite con los otros hilos por el derecho de sincronizarse con el objeto. Unavez que ha ganado el control del objeto, todos sus derechos de sincronizacin en el objeto se

    restablecen al estado que tenan en el momento en que se invoco al mtodo wai t ( ) . El hilo luegoregresa del mtodo wai t ( ) .

    Lanza:I l l egal Ar gument Except i on Si el valor de t i meout es negativo.I l l egal Moni t or St at eExcept i on Si el hilo actual no es el dueo del monitor delobjeto.

    I nt er r upt edExcept i on Si cualquier hilo ha interrumpido el corriente hilo antes omientras el hilo actual est esperando por una notificacin. El estado de interrumpido delhilo actual se limpia cuando se lanza la excepcin.

  • 5/25/2018 Tema 12 - Hilos en Java

    18/24

    446 Hilos en Java

    ITSON Manuel Domitsu Kono

    Tabla 12.4 Mtodos de la Clase ObjectEmpleados con Hilos. Cont.publ i c f i nal voi d wait( l ong ti meout , i nt nanos)

    t hr ows I nt er r upt edExcept i on

    Hace que el hilo actual espere hasta que otro hilo invoque al mtodo not i f y( ) o al mtodonot i f yAl l ( ) de este objeto, u otro hilo interrumpa al hilo actual o la cantidad de tiempo dado

    por sus parmetros haya transcurrido.

    El mtodo es similar al mtodo wait con un solo parmetro, pero permite un control ms fino sobrela cantidad de tiempo a esperar por la notificacin antes de continuar. El tiempo a esperar medidoen nanosegundos est dada por:

    1000000*t i meout +nanos

    En todos los dems aspectos, este mtodo es similar al mtodo wai t ( l ong

    t i meout ) . En particular wai t ( 0, 0) significa lo mismo quewai t ( 0) .publ i c f i nal voi d wait( ) t hr ows I nt er r upt edExcept i on

    Este mtodo se comporta como si se llamara a wai t ( 0) .

    Al ejecutar el mtodo wai t ( ) desde un bloque sincronizado, un hilo libera elcandado y se duerme. Un hilo puede hacer eso si necesita esperar que pase algoen otra parte de la aplicacin. Ms tarde cuando el evento esperado pase, el hiloque est en ejecucin llama al mtodo not i f y( ) desde un bloque sincronizadoen el mismo objeto. Entonces el primer hilo se despierta y empieza a tratar deadquirir el candado otra vez.

    Cuando el primer hilo logra obtener de nuevo el candado, contina desde el puntoen que se qued. Sin embargo, el hilo que estaba esperando puede no adquirir elcandado inmediatamente (o tal vez, nunca). Depende de cuando el segundo hilo

    eventualmente libere el candado, y que hilo logre atraparlo enseguida. El primerhilo no se despertar a menos que otro hilo llame al mtodo not i f y( ) . Hay unaversin sobrecargada de wai t ( ) , que permite especificar un tiempo deexpiracin. Si otro hilo no invoca al mtodo not i f y( ) en el tiempo especificado,el hilo se despierta automticamente.

    Para cada llamada a not i f y( ) , Java despierta uno de los mtodos dormidos enla llamada a wai t ( ) . Si hay varios mtodos esperando, Java selecciona al primerhilo en base a primero en entrar primero en salir.

    La clase Obj ect tambin tiene el mtodo not i f yAl l ( ) que permite despertar atodos los hilos esperando. En la mayora de los casos se desea llamar anot i f yAl l ( ) en vez de not i f y( ) .

  • 5/25/2018 Tema 12 - Hilos en Java

    19/24

    Tema 12 Hilos en Java 447

    ITSON Manuel Domitsu Kono

    Ejemplo sobre Esperar y Noti ficar

    Considere el siguiente ejemplo. Se quiere simular el comportamiento de una cola ala que llegan clientes a ser atendidos. Los clientes son atendidos en una o varias

    estaciones. Para modelar la atencin que recibe el cliente se tiene la claseTar ea:

    Tarea.java/ ** Tarea. j ava** @aut hor mdomi t su*/

    package col a;

    i mpor t j ava. ut i l . Dat e;

    publ i c cl ass Tarea {i nt numTar ea;

    Dat e t i meSt amp;i nt dur aci on;

    publ i c Tar ea( i nt numTar ea) {t hi s. numTarea = numTarea;t i meStamp = new Dat e( ) ;dur aci on = Gener adorAl eatori o. get Poi sson( 1) ;

    }

    publ i c i nt get Dur aci on( ) {r et ur n dur aci on;

    }

    publ i c i nt get NumTar ea( ) {r et urn numTarea;}

    publ i c Dat e getTi meSt amp( ) {r etur n t i meSt amp;

    }

    @Over r i depubl i c St r i ng t oSt r i ng( ) {

    r et urn "Tarea " + numTar ea + " : " + dur aci on + " , "+ t i meSt amp. t oSt r i ng( ) ;

    }}

    El atributo dur aci onde la claseTar ea, modela el tiempo que el cliente tarda enser atendido. Para establecer ese tiempo se utiliza un generador de nmerosaleatorios que tiene una distribucin de probabilidad de Poisson. Su cdigo se

    encuentra en la clase Gener ador Al eat or i o.

  • 5/25/2018 Tema 12 - Hilos en Java

    20/24

    448 Hilos en Java

    ITSON Manuel Domitsu Kono

    GeneradorAleatorio.java/ ** Gener ador Al eat or i o. j ava** @aut hor mdomi t su*/

    package col a;publ i c cl ass Gener ador Al eat or i o {

    publ i c st at i c i nt get Poi sson( doubl e l ambda) {doubl e L = Mat h. exp( - l ambda) ;doubl e p = 1. 0;i nt k = 0;

    do {k++;p *= Mat h. r andom( ) ;

    } whi l e (p > L) ;

    r et ur n k - 1;

    }}

    La clase Col aTareasrepresenta la cola a la que llegan los clientes en espera deser atendidos. La cola tiene un tamao mximo de 5. Si la cola est llena, losclientes deben esperan a que haya espacio para entrar a la cola.

    ColaTareas.java/ ** Col aTar eas. j ava** @aut hor mdomi t su

    */package col a;

    i mport j ava. ut i l . Arr ayLi st ;i mpor t j ava. ut i l . Li s t ;

    publ i c cl ass Col aTar eas {pri vat e Li st col aTareas = new Ar r ayLi st ( ) ;pr i vat e st at i c f i nal i nt MAXQUEUE = 5;

    publ i c synchr oni zed voi d ponTar ea(Tar ea t area)t hr ows I nt er r upt edExcept i on {

    whi l e ( col aTar eas. si ze( ) == MAXQUEUE) {wai t ( ) ;}

    col aTar eas. add( t ar ea) ;not i f y( ) ;

    }

    publ i c synchr oni zed Tar ea obt enTar ea( ) t hr ows I nt er r upt edExcept i on {not i f y( ) ;

  • 5/25/2018 Tema 12 - Hilos en Java

    21/24

    Tema 12 Hilos en Java 449

    ITSON Manuel Domitsu Kono

    whi l e ( col aTar eas. si ze( ) == 0) {wai t ( ) ;

    }Tar ea t ar ea = col aTareas. get ( 0) ;col aTar eas. r emove( t ar ea) ;

    r et ur n tarea;}

    publ i c synchr oni zed i nt get Tamano() {r et ur n col aTar eas. si ze( ) ;

    }}

    Para modelar el arribo de los clientes se tiene el mtodo pr oduceTarea( ) queagrega un cliente a la cola. Para establecer ese tiempo entre arribos de losclientes se utiliza un generador de nmeros aleatorios que tiene una distribucinde probabilidad de Poisson. Los clientes llegan ms rpido de lo que pueden seratendidos.

    Productor.java/ ** Pr oduct or . j ava** @aut hor mdomi t su*/

    package hi l os;

    i mpor t col a. Col aTar eas;i mpor t col a. Gener adorAl eator i o;i mpor t col a. Tar ea;

    publ i c cl ass Product or ext ends Thr ead {pr i vat e st at i c f i nal i nt MAX_TAREAS = 10;pr i vat e Col aTar eas col aTareas;

    publ i c Pr oduct or ( Col aTar eas col aTar eas) {t hi s. col aTar eas = col aTar eas;

    }

    @Over r i depubl i c voi d r un( ) {

    i nt i = 0;try {

    whi l e ( i < MAX_TAREAS) {

    pr oduceTarea( i ) ;

    / / Si mul a el t i empo ent r e l l egadassl eep( 1000 * Gener ador Al eat ori o. get Poi sson( 0. 5) ) ;i ++;

    }} cat ch (I nt er r upt edExcept i on e) {}

    }

  • 5/25/2018 Tema 12 - Hilos en Java

    22/24

    450 Hilos en Java

    ITSON Manuel Domitsu Kono

    pr i vat e voi d pr oduceTar ea(i nt i ) t hr ows I nt er r upt edExcept i on {Tar ea t ar ea = new Tar ea( i ) ;

    col aTar eas. ponTar ea( t ar ea) ;Syst em. out . pr i nt l n( "Product or : " + t ar ea + ", "

    + col aTareas. get Tamano( ) ) ;}

    }

    Para modelar la atencin de los clientes se tiene la clase Consumi dor .

    Consumidor.java/ ** Consumi dor . j ava** @aut hor mdomi t su*/

    package hi l os;

    i mpor t col a. Col aTar eas;i mpor t col a. Tar ea;

    publ i c cl ass Consumi dor extends Thread {pr i vat e Col aTar eas col aTareas;

    publ i c Consumi dor ( St r i ng nombr e, Col aTareas col aTareas) {super( nombr e) ;t hi s. col aTar eas = col aTar eas;

    }

    @Over r i depubl i c voi d r un( ) {

    try {whi l e ( t r ue) {

    Tarea t ar ea = consumeTarea( ) ;sl eep( 1000 * tar ea. get Dur aci on( ) ) ;

    }} cat ch ( I nt er r upt edExcept i on e) {}

    }

    publ i c Tar ea consumeTarea( ) t hrows I nt err upt edExcept i on {Tar ea t ar ea;

    t area = col aTareas. obt enTar ea( ) ;Syst em. out . pr i nt l n( getName() + " : " + t area+ " , "

    + col aTareas. getTamano( ) ) ;

    r et ur n tarea;}

    }

    En la siguiente clase de prueba se simula el caso de que hay una solo estacin deatencin para los clientes:

  • 5/25/2018 Tema 12 - Hilos en Java

    23/24

    Tema 12 Hilos en Java 451

    ITSON Manuel Domitsu Kono

    Prueba.java/ ** Pr ueba. j ava** @aut hor mdomi t su*/

    package pr uebas;

    i mpor t col a. Col aTar eas;i mpor t hi l os. Consumi dor ;i mpor t hi l os. Pr oductor;

    / * *** @aut hor mdomi t su*/

    publ i c cl ass Pr ueba {publ i c st at i c voi d mai n( St r i ng[ ] ar gs) {

    Col aTareas col aMensaj es = new Col aTareas( ) ;

    Product or product or = new Productor( col aMensaj es) ;Consumi dor consumi dor1 = new Consumi dor( "Consumi dor 1",

    col aMensaj es) ;

    product or . start ( ) ;consumi dor 1. st ar t ( ) ;

    }}

    Lo siguiente es una corrida del programa anterior.

    Product or : Tar ea 0: 1, Fr i Apr 29 00: 24: 37 MST 2011, 0Product or : Tar ea 1: 3, Fr i Apr 29 00: 24: 37 MST 2011, 1Product or : Tar ea 2: 0, Fr i Apr 29 00: 24: 37 MST 2011, 2Product or : Tar ea 3: 0, Fr i Apr 29 00: 24: 37 MST 2011, 3Consumi dor 1: Tarea 0: 1, Fr i Apr 29 00: 24: 37 MST 2011, 3Consumi dor 1: Tarea 1: 3, Fr i Apr 29 00: 24: 37 MST 2011, 2Product or : Tar ea 4: 1, Fr i Apr 29 00: 24: 39 MST 2011, 3Product or : Tar ea 5: 1, Fr i Apr 29 00: 24: 40 MST 2011, 4Product or : Tar ea 6: 0, Fr i Apr 29 00: 24: 40 MST 2011, 5Consumi dor 1: Tarea 2: 0, Fr i Apr 29 00: 24: 37 MST 2011, 4Consumi dor 1: Tarea 3: 0, Fr i Apr 29 00: 24: 37 MST 2011, 3Consumi dor 1: Tarea 4: 1, Fr i Apr 29 00: 24: 39 MST 2011, 2Product or : Tar ea 7: 1, Fr i Apr 29 00: 24: 40 MST 2011, 3Product or : Tar ea 8: 0, Fr i Apr 29 00: 24: 42 MST 2011, 3

    Consumi dor 1: Tarea 5: 1, Fr i Apr 29 00: 24: 40 MST 2011, 3Consumi dor 1: Tarea 6: 0, Fr i Apr 29 00: 24: 40 MST 2011, 3Product or : Tar ea 9: 1, Fr i Apr 29 00: 24: 43 MST 2011, 3Consumi dor 1: Tarea 7: 1, Fr i Apr 29 00: 24: 40 MST 2011, 2Consumi dor 1: Tarea 8: 0, Fr i Apr 29 00: 24: 42 MST 2011, 1Consumi dor 1: Tarea 9: 1, Fr i Apr 29 00: 24: 43 MST 2011, 0

    En la siguiente clase de prueba se simula el caso de que hay dos estaciones deatencin para los clientes:

  • 5/25/2018 Tema 12 - Hilos en Java

    24/24

    452 Hilos en Java

    ITSON Manuel Domitsu Kono

    Prueba.java/ ** Pr ueba. j ava** @aut hor mdomi t su*/

    package pr uebas;

    i mpor t col a. Col aTar eas;i mpor t hi l os. Consumi dor ;i mpor t hi l os. Pr oductor;

    / * *** @aut hor mdomi t su*/

    publ i c cl ass Pr ueba {publ i c st at i c voi d mai n( St r i ng[ ] ar gs) {

    Col aTareas col aMensaj es = new Col aTareas( ) ;

    Product or product or = new Productor( col aMensaj es) ;Consumi dor consumi dor1 = new Consumi dor( "Consumi dor 1",

    col aMensaj es) ;Consumi dor consumi dor2 = new Consumi dor( "Consumi dor 2",

    col aMensaj es) ;

    product or . start ( ) ;consumi dor 1. st ar t ( ) ;consumi dor 2. st ar t ( ) ;

    }}

    Lo siguiente es una corrida del programa anterior.

    Product or : Tar ea 0: 1, Fr i Apr 29 00: 26: 58 MST 2011, 0Consumi dor 2: Tarea 0: 1, Fr i Apr 29 00: 26: 58 MST 2011, 0Consumi dor 1: Tarea 1: 4, Fr i Apr 29 00: 26: 59 MST 2011, 0Product or : Tar ea 1: 4, Fr i Apr 29 00: 26: 59 MST 2011, 0Product or : Tar ea 2: 2, Fr i Apr 29 00: 27: 00 MST 2011, 0Consumi dor 2: Tarea 2: 2, Fr i Apr 29 00: 27: 00 MST 2011, 0Product or : Tar ea 3: 0, Fr i Apr 29 00: 27: 01 MST 2011, 1Product or : Tar ea 4: 0, Fr i Apr 29 00: 27: 01 MST 2011, 2Product or : Tar ea 5: 0, Fr i Apr 29 00: 27: 01 MST 2011, 3Product or : Tar ea 6: 2, Fr i Apr 29 00: 27: 01 MST 2011, 4Product or : Tar ea 7: 0, Fr i Apr 29 00: 27: 01 MST 2011, 5

    Consumi dor 2: Tarea 3: 0, Fr i Apr 29 00: 27: 01 MST 2011, 4Consumi dor 2: Tarea 4: 0, Fr i Apr 29 00: 27: 01 MST 2011, 3Consumi dor 2: Tarea 5: 0, Fr i Apr 29 00: 27: 01 MST 2011, 2Consumi dor 2: Tarea 6: 2, Fr i Apr 29 00: 27: 01 MST 2011, 1Consumi dor 1: Tarea 7: 0, Fr i Apr 29 00: 27: 01 MST 2011, 0Product or : Tar ea 8: 2, Fr i Apr 29 00: 27: 03 MST 2011, 0Product or : Tar ea 9: 0, Fr i Apr 29 00: 27: 03 MST 2011, 1Consumi dor 1: Tarea 8: 2, Fr i Apr 29 00: 27: 03 MST 2011, 0Consumi dor 2: Tarea 9: 0, Fr i Apr 29 00: 27: 03 MST 2011, 0