Ir al contenido principal

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í.

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.

    ResponderEliminar
  2. 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.

    ResponderEliminar
  3. 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.

    ResponderEliminar
  4. 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.

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

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

    ResponderEliminar
  7. exelente informacion ¡¡¡¡

    ResponderEliminar
  8. como hago el método burbuja con un Hilo???

    ResponderEliminar
  9. 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();
    }

    }
    }

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

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

    ResponderEliminar
  12. 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)
    {}

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

    ResponderEliminar
  14. 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?

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

    ResponderEliminar
  16. 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.

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

    ResponderEliminar
  18. 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

    ResponderEliminar
  19. 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

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

    ResponderEliminar
  21. 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!

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

    ResponderEliminar
  23. 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!

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

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

    ResponderEliminar

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.

Entradas más populares de este blog

3 sencillos pasos para tramitar la ayuda por desempleo de la AFORE

¿Tienes dinero ahorrado en tu AFORE y en este momento no estás trabajando o estás trabajando pero no tienes seguro social?
Si respondiste sí a la pregunta anterior entonces hay una buena noticia para ti: puedes retirar una parte del dinero que tienes ahorrado. Y lo mejor, es muy sencillo.
En este artículo te diré paso a paso qué hacer para obtener ese dinero, sin tecnicismos legales ni nada por el estilo, simple y sencillamente lo que necesitas saber.
Paso Número 1: Obtener los últimos 2 estados de cuenta de tu Afore
Esto en la mayoría de los casos es sumamente sencillo ya que dichos estados de cuenta llegan directamente al domicilio del ahorrador, si este es tu caso puedes saltar lo restante en este punto y continuar con el paso número 2, en caso contrario sigue leyendo…

Si no tienes tus estados de cuenta debes ponerte en contacto con la empresa encargada de administrar tu ahorro para que te los proporcione, normalmente te van a pedir una identificación oficial, comprobante de domici…

Conectar una base de datos en MySQL con NetBeans

NetBeans es una plataforma para el desarrollo de aplicaciones de escritorio usando Java y a un Entorno integrado de desarrollo (IDE) desarrollado usando la Plataforma NetBeans.

Si eres un programador y desarrollas tus aplicaciones en Java seguramente necesitarás conectar una base de datos tipo MySQL a este entorno algún día, bueno, si lo necesitas ahora, he aquí una explicación paso a paso de cómo conectar ambas herramientas.

4 extraordinarias aplicaciones espía para Android

Le andas haciendo al James Bond y necesitas grabar video, voz o tomar fotos desde tu dispositivo Android sin ser notado? Aquí 4 excelentes aplicaciones que facilitarán tus hazañas de 007 en menos de lo que canta un gallo.

Conexión, consulta y ejecución de sentencias en MySQL con Java

Anteriormente escribí este mismo artículo pero para bases de datos en Oracle. En este artículo prácticamente me copio y pego para explicar paso a paso cómo realizar la conexión a MySQL en Java, así como la forma de realizar consultas a los registros existentes y ejecutar sentencias de inserción, borrado y actualización de datos.Al final del artículo tendremos una clase que encapsulará todos los procedimientos necesarios para trabajar con la base de datos.

c606 c6nf5g4r6 e3 tec3ad6 [Como configurar el teclado]

¿Problemas al escribir con el teclado? ¿Tratas de escribir la letra ‘o’ y sale el número ‘6’ o algo por el estilo? La solución puede ser más simple de lo que parece.

La solución a tu problema tras el salto...