Hilos en Java(Threads) parte 1

Hilos en Java

Para hablar de hilos en Java primeramente se necesita entender lo que es un hilo. Un hilo es un proceso que se está ejecutando en un momento determinado en nuestro sistema operativo, como cualquier otra tarea, esto se realiza directamente en el procesador. Existen los llamados 'demonios' que son los procesos que define el sistema en sí para poder funcionar y otros que llamaremos los hilos definidos por el usuario o por el programador, estos últimos son procesos a los que el programador define un comportamiento e inicia en un momento específico.




En Java, el proceso que siempre se ejecuta es el llamado main que es a partir del cual se inicia prácticamente todo el comportamiento de nuestra aplicación, y en ocasiones a la aplicación le basta con este solo proceso para funcionar de manera adecuada, sin embargo, existen algunas aplicaciones que requieren más de un proceso (o hilo) ejecutándose al mismo tiempo (multithreading), por ejemplo, se tiene una aplicación de una tienda departamental de la cual se actualizan los precios y mercancías varias veces al día a través de la red, se verifícan los nuevos descuentos y demás pero que a su vez es la encargada de registrar las compras y todos movimientos que se realice con la mercancía dentro de la tienda, si se decide que dicha aplicación trabajará de la manera simple y con un solo proceso (o hilo), el trabajo de la actualización de precios y mercancías debe de finalizar antes de que alguien pueda hacer algún movimiento con un producto dentro de la tienda, o viceversa, ya que la aplicación no es capaz de mantener el proceso de actualización en segundo plano mientras se registra un movimiento. Si se toma este modelo mono-hilo el tiempo y dinero que se perderá dentro de la tienda será muchísimo mayor comparando con un modelo multi-hilo. En un modelo multi-hilo se pueden realizar todas las actualizaciones en segundo plano mientras se registra una o más ventas o movimientos, cada proceso independiente del otro viviendo o ejecutándose al mismo tiempo dentro de la misma aplicación.


Al hablar de multi-hilo pudiera parecer que necesitamos más de un procesador para realizar dichas tareas pero no es así, el procesador mismo junto con la máquina virtual de Java gestionan el flujo de trabajo y dan la impresión de que se puede ejecutar más de algún proceso al mismo tiempo (aunque en términos estrictos eso no es posible), de cualquier manera no ahondaré en el funcionamiento del procesador, basta con entender que en Java, 2 o más procesos pueden ejecutarse al mismo tiempo dentro de una misma aplicación y para ello son necesarios los Threads o hilos.

Ahora que ya entendemos lo que son los hilos pasaremos a una definición un poco más específica de Java. En Java un hilo o Thread puede ser 2 cosas:

+ Una instancia de la clase java.lang.Thread
+ Un proceso en ejecución

Una instancia de la clase java.lang.Thread, no es más que cualquier otro objeto, con variables y métodos predefinidos. Un proceso en ejecución es un proceso individual que realiza una tarea o trabajo, tiene su propia pila de información independiente a la de la aplicación principal.

Es necesario entender que el comportamiento de los hilos o threads varía de acuerdo a la máquina virtual, incluso el concepto más importante a entender con los hilos en Java es que...

"Cuando se trata de hilos, muy pocas cosas está garantizadas"

...por ello se debe ser cautelosos al momento de interpretar el comportamiento de un hilo. Pasemos al código.


Crear un hilo (Thread)::

Un hilo o proceso en Java comienza con una instancia de la clase java.lang.Thread, si analizamos la estructura de dicha clase podremos encontrar bastantes métodos que nos ayudan a controlar el comportamiento de los hilos, desde crear un hilo, iniciarlo, pausar su ejecución, etc. Aquellos métodos que siempre tenemos que tener presentes con respecto a los hilos son:

  • start()
  • yield()
  • sleep()
  • run()

La acción sucede dentro del método run(), digamos que el código que se encuentra dentro de dicho método es el trabajo por hacer, por lo tanto, si queremos realizar diversas operaciones cada una simultánea pero de manera independiente, tendremos varias clases, cada una con su respectivo método run(). Dentro del método run() puede haber llamados a otros métodos como en cualquier otro método común, pero la pila de ejecución del nuevo proceso siempre comenzará a partir de la llamada al método run().

Definir un nuevo hilo::

Para definir e instanciar un nuevo Thread (hilo, proceso) existen 2 formas:

+ Extendiendo (o heredando) a la clase java.lang.Thread
+ Implementando la interfaz Runnable

Normalmente en el trabajo diario es más recomendable el implementar la interfaz Runnable, en lugar de extender la clase java.lang.Thread debido a que una clase solamente puede heredar o extender otra sola clase pero puede implementar muchas interfaces. Si extendemos de la clase java.lang.Thread no podremos extender o heredar ninguna otra, pero si implementamos la interfaz Runnable, podremos heredar cualquier otra clase e implementar muchas otras interfaces sin perder el comportamiento de la nuestra.

En cualquiera de los 2 casos, ya sea heredando de java.lang.Thread o implementando Runnable, al definir e instanciar un nuevo hilo, necesitaremos de redefinir el método run(), veamos cómo hacerlo.

Extendiendo java.lang.Thread::

1.- Hereda a la clase java.lang.Thread por medio de la palabra 'extends'.
2.- Redefine el método run().

P. ej.

class MiHilo extends Thread{
public void run(){
System.out.println("Trabajo por hacer dentro de MiHilo");
}
}

Nuevamente, esto no es recomendable ya que al heredar la clase Thread, no podrás heredar nada más.

Toma en cuenta que puedes sobrecargar el método run() sin ningún problema como se muestra a continuación...

class MiHilo extends Thread{
public void run(){
System.out.println("Trabajo por hacer dentro de MiHilo");
}

public void run(String s){
System.out.println("La cadena ingresada es " + s);
}
}

...sin embargo, al realizar esto, no estarás utilizando tu nuevo método public void run (String s) en un proceso separado, es un simple método común y corriente como cualquier otro que tienes que mandar llamar de manera independiente ya que los hilos trabajan con un método run() sin argumentos.

Implementando la interfaz Runnable::

1.- Implementa a la interfaz Runnable por medio de la palabra 'implements'.
2.- Redefine el método run().

P. ej.

class MiHilo implements Runnable{
public void run(){
System.out.println("Trabajo por hacer dentro de MiHilo");
}
}

Independientemente de cómo definas tu hilo (por medio de extends Thread o implements Runnable), el hilo tendrá el mismo comportamiento.

Instanciando un hilo o Thread::

Debemos recordar que cada hilo de ejecución es una instancia de la clase Thread, independientemente de si tu método run() está dentro de una subclase de Thread o en una implementación de la interfaz Runnable, se necesita un objeto tipo Thread para realizar el trabajo.

Si has extendido la clase Thread, el instanciar el hilo es realmente simple:

MiHilo h = new MiHilo();

Si has implementado la interfaz Runnable, es un poquito más complicado, pero solo un poco:

MiHilo h = new MiHilo();
Thread t = new Thread(h); // Pasas tu implementación de Runnable al nuevo Thread

Puedes pasar una misma instancia de una clase que implementa Runnable a diversos objetos de tipo Thread...

public class PruebaHilos{

public static void main (String[] args)
{
MiHilo h = new MiHilo();
Thread t1 = new Thread(h);
Thread t2 = new Thread(h);
Thread t3 = new Thread(h);
}
}

El pasar un solo objeto tipo MiHilo a varios objetos tipo Thread significa que el trabajo que se encuentra dentro del método run() de MiHilo se realizará en diversas ocasiones, o lo que es lo mismo, varios hilos realizarán el mismo trabajo.

Hasta aquí le dejamos con la primera parte...

Más sobre programación en Java aquí.

26 comentarios:

  1. Despues de esto me han quedado dudas el primer metodo heredar de la clase thread no sirve entonces ya que nadamas puedo usarlo una vez y quisiera saber un ejemplo aplicativo es decir algo que pueda servirme realmente.

  1. Monillo007 dijo...:

    Que tal Sergio!

    Te recomiendo leer las siguientes partes de este tema de Hilos en Java para que puedas aclarar tus dudas, en caso de que continúen estoy para servirte.

    Saludox.

  1. Anónimo dijo...:

    necesito un programa que haga lo siguiente:
    -que yo pueda meter texto en una lista pero que al dar la palabra FIN me guarde los datos de la lista y que salga del programa.
    espero puedan ayudar.

  1. Monillo007 dijo...:

    Qué tal!

    Antes que todo disculpa la tardanza. Te comento que el propósito de este blog es aprender para aplicar lo que podemos compartir, no es costumbre (ni ético) atender peticiones de tareas o proyectos, espero tu comprensión.

    Saludox.

  1. Anónimo dijo...:

    Muchas gracias por este curso. Me está ayudando mucho a comprender los hilos.

  1. Anónimo dijo...:

    ¿donde estan las siguientes partes ? no encuentro enlaces.... gracias!.

  1. Anónimo dijo...:

    exelente informacion ¡¡¡¡

  1. Anónimo dijo...:

    como hago el método burbuja con un Hilo???

  1. Anónimo dijo...:

    hola buenas noches
    cuando quiero correr el prog.. MiHilo me sale el siguente error :
    java.lang.NoSuchMethodError: main
    Exception in thread "main"
    Process completed.

    aun despues de que me aparece Process completed
    espero me pudieras ayudar por favor..
    con cualquier otro prog..si lo compila :

    import java.io.*;
    public class sumanumeros {

    public static void main(String[] args) {

    InputStreamReader isr = new InputStreamReader(System.in);
    BufferedReader br = new BufferedReader(isr);

    try{

    System.out.print("Ingresa un numero entero: ");
    int num1 = Integer.parseInt(br.readLine());


    int num2 = num1 + 100;
    int resultado = 0;
    int total = 0;

    for(int i = num1; i < num2; i++) {

    resultado = i;
    total = resultado + total;


    }
    System.out.println("La sumatoria de los 100 numeros posteriores al ingresado es: " + total );

    }
    catch(Exception e)
    {
    e.printStackTrace();
    }

    }
    }

  1. Anónimo dijo...:

    Muchas gracias, no conocia esta pagina, me ayudo mucho a comprender los hilos

  1. Anónimo dijo...:

    uyyyyyyyy aqui esta mas explicadito que en otras paginaz ... chevre tio me sirve mucho esta informacion ya que toy estudiando pz ..... xD!

  1. Anónimo dijo...:

    Anónimo
    8 de abril de 2011 01:02


    el error que te aparece es porque te falta incluir las siguientes lineas de codigo

    public static void main(String[] args)
    {}

  1. fabian dijo...:

    ny bien que buena pagina pero donde estan las otras partes me podrian decir

  1. Anónimo dijo...:

    Hola a todos, quiciera saber si me pueden apoyar, tengo que hacer una aplicacion que busque en una tabla y dependiendo de valores que encuentre, debo ejecutar procedimientos de una clase externa ( jar ), debido a que no deseo a que mi aplicacion espere a la respuesta de cada procedimiento, si no que mi aplicacion solo mande que se ejecute dichos procedimientos y estos se ejecuten independiente. pero a la vez los llamados a los procedimientos que duren mas de X tiempo que mi aplicacion los pueda terminar o matar.

    mi duda principal es posible esto con hilos?

  1. Anónimo dijo...:

    Mi consulta es si un thread es recomendable para un juego en java o deberia usarse otros conceptos

  1. Luis Navarro dijo...:

    Te comento que conozco poco del desarrollo de juegos, sin embargo, he consultado con algunas personas más familiarizadas en el tema y me comentan que usualmente se utilizan los hilos.

    Saludos.

  1. PAZ PERDOMO dijo...:

    ME FASCINA ESTE BLOG..FELICITACIONES...ÉXITOS

  1. Anónimo dijo...:

    hola amigos, para hacer juegos, ya sean parecidos como el primer juego de Mario Bros para Nintendo claro que se necesitan hilos, ya que estos procesos hacen que tu programa corra con mayor facilidad y menor tiempo, ese tema lo vimos en la clase de programacion, y se me hizo muy interesante y pues les comparto lo que vimos, incluso un compañero se avento un juego llamado "TAMBO" super buenisimo ya que es una recopilacion de de MARIO BROS y RAMBO jajaja bueno amigos suerte a todos. I

  1. Anónimo dijo...:

    Hola muy buena la info! En algún lugar vi que era posible hacer algo así:
    private void mostrarMensaje( final String mensajeAMostrar ){
    SwingUtilities.invokeLater(
    new Runnable() {
    public void run() {

    Mi pregunta es, cómo hago que al crear el Thread este quede "atado" a este método run, sin tener q hacer una clase como las que explicaste arriba.
    Gracias

  1. deditos dijo...:

    Seria un buen comienzo para saber de hilos ?? bueno a leerlo..ojala me sirvaa , igualmente m gustaria ke me ayudes ..

  1. Marcos Salazar dijo...:

    Muchísimas gracias, recién estoy viendo este tema y tus aportes acerca de hilos me han caído como anillo al dedo, cuando más los necesito, tu blog es lo máximo, sigue así, lo estás haciendo muy bien compa, saludos!

  1. cuchox dijo...:

    Excelente aporte, esta es la primera publicación de tu serie y ya voy entendiendo muy bien, felicitaciones.

  1. Anónimo dijo...:

    HOla, primero que nada gracias por el tutorial, ya lei los 5 y esta muy completo. Desde ayer estoy intentando que en los hilos que lanzo desde el principal se recupere una entidad, al intentar hacerlo me tira una exepcion que dejo a continuación:

    java.lang.NullPointerException at com.splwg.base.api.datatypes.SingleFieldId.getEntity(SingleFieldId.java:168) at com.splwg.base.api.datatypes.SingleFieldId.getEntity(SingleFieldId.java:168)
    at com.splwg.cm.domain.common.LucasHilos.run(LucasHilos.java:47)
    at java.lang.Thread.run(Thread.java:595)




    lo raro es que si yo del principal ejecuto el hilo con .(run) la entidad la recupera, pero al ejecutarlo con el .start(), me lanza esta excepcion.

    Gracias por todo,

    Saludos!

  1. ivan laverde dijo...:

    re falto denotar el llamado a hilo.run(); en este caso seria hilo.star();

  1. SoftMAS SM dijo...:

    Muy buena explicación, es un tema complejo para entender y explicar. Excelente trabajo.
    SoftMAS Desarrollo de Software.
    http://soft-mas.com

Publicar un comentario

Este es un espacio abierto, puedes escribir lo que gustes respetando los siguientes puntos:

1.- Lo que escribas esté relacionado con el post, si gustas contactarme puedes hacerlo aqui.

2.- Todo es cuestionable, aunque ten en cuenta que existen formas de hacerlo, evita las agresiones y revisa tu lenguaje antes de publicar un comentario.

3.- Siempre hay tres verdades: tu verdad, mi verdad y la verdad, por lo que opiniones diferentes no necesariamente son equivocadas.

4.- Los comentarios son una forma de discusión abierta, por lo que al publicar uno, implícitamente entras a una discusión, con todo lo que esto representa.

5. Me reservo el derecho de eliminar comentarios que no respeten las condiciones mencionadas anteriormente.

Toma en cuenta que puedes utilizar emoticones en tu comentario, para ver una lista de los disponibles da clic en este enlace.

 
Monillo007 © 2010 | Designed by Trucks, Manual Bookmarking | Elegant Themes