Tutorial de subprocesos múltiples en Java con programa y ejemplos


Cualquier aplicación puede tener múltiples procesos (instancias). Cada uno de estos procesos se puede asignar como un solo subproceso o como múltiples subprocesos. Veremos en este tutorial cómo realizar múltiples tareas al mismo tiempo y también aprenderemos más sobre subprocesos y syncsincronización entre hilos.

En este tutorial de multiproceso en Java, aprenderemos:

¿Qué es un hilo único?

Un solo hilo en Java es básicamente una unidad de procesamiento liviana y la más pequeña. Java utiliza subprocesos mediante el uso de una "Clase de subproceso".

Hay dos tipos de hilo: hilo de usuario y hilo de demonio (Los hilos de demonio se usan cuando queremos limpiar la aplicación y se usan en segundo plano).

Cuando se inicia una aplicación por primera vez, se crea un hilo de usuario. Publique eso, podemos crear muchos hilos de usuario y hilos de demonio.

Ejemplo de hilo único:

package demotest;

public class GuruThread
{
       public static void main(String[] args) {
              System.out.println("Single Thread");
       }
}

Ventajas del hilo único:

  • Reduce la sobrecarga en la aplicación ya que se ejecuta un solo subproceso en el sistema.
  • Además, reduce el coste de mantenimiento de la aplicación.

¿Qué es el subproceso múltiple en Java?

multihilo en Java es un proceso de ejecución de dos o más subprocesos simultáneamenteneously para la máxima utilización de la CPU. Las aplicaciones multiproceso ejecutan dos o más subprocesos al mismo tiempo. Por lo tanto, también se le conoce como Concurrencia en Java. Cada hilo corre paralelo entre sí. Varios subprocesos no asignan un área de memoria separada, por lo que ahorran memoria. Además, el cambio de contexto entre subprocesos lleva menos tiempo.

Ejemplo de hilo múltiple:

package demotest;
public class GuruThread1 implements Runnable
{
       public static void main(String[] args) {
        Thread guruThread1 = new Thread("Guru1");
        Thread guruThread2 = new Thread("Guru2");
        guruThread1.start();
        guruThread2.start();
        System.out.println("Thread names are following:");
        System.out.println(guruThread1.getName());
        System.out.println(guruThread2.getName());
    }
    @Override
    public void run() {
    }
}

Ventajas del multiproceso:

  • Los usuarios no están bloqueados porque los hilos son independientes y podemos realizar múltiples operaciones a veces
  • Como tal, los subprocesos son independientes, los otros subprocesos no se verán afectados si un subproceso cumple con una excepción.

Ciclo de vida del hilo en Java

El ciclo de vida de un hilo:

Ciclo de vida del hilo en Java
Ciclo de vida del hilo en Java

Hay varias etapas del ciclo de vida del hilo, como se muestra en el diagrama anterior:

  1. Nuevo
  2. Ejecutable
  3. Correr
  4. Esperando
  5. Muertos
  1. Nuevo: En esta fase, el hilo se crea utilizando la clase "Clase de hilo". Permanece en este estado hasta que el programa comienza la amenaza. También se le conoce como hilo nacido.
  2. Ejecutable: En esta página, la instancia del hilo se invoca con un método de inicio. El control del hilo se le da al programador para finalizar la ejecución. Depende del programador si se debe ejecutar el hilo.
  3. Corriendo: Cuando el hilo comienza a ejecutarse, el estado cambia al estado "en ejecución". El programador selecciona un subproceso del grupo de subprocesos y comienza a ejecutarse en la aplicación.
  4. Esperando: Este es el estado en el que un hilo tiene que esperar. Como se ejecutan varios subprocesos en la aplicación, es necesario syncsincronización entre hilos. Por lo tanto, un hilo tiene que esperar hasta que se ejecute el otro hilo. Por lo tanto, este estado se denomina estado de espera.
  5. Muerto: Este es el estado en el que finaliza el hilo. El hilo está en estado de ejecución y tan pronto como completa el procesamiento, está en "estado muerto".


Algunos de los métodos comúnmente utilizados para subprocesos son:

Método Descripción
comienzo() Este método inicia la ejecución del hilo y JVM llama al método run() en el hilo.
Dormir (int milisegundos) Este método hace que el subproceso entre en suspensión, por lo que la ejecución del subproceso se detendrá durante los milisegundos proporcionados y luego de eso, el subproceso comienza a ejecutarse nuevamente. Esta ayuda en syncronización de los hilos.
getName () Devuelve el nombre del hilo.
establecerPrioridad(int nuevaprioridad) Cambia la prioridad del hilo.
producir () Hace que el hilo actual se detenga y se ejecuten otros hilos.

Ejemplo: En este ejemplo de programa multiproceso en Java, crearemos un hilo y exploraremos los métodos integrados disponibles para los hilos.

package demotest;
public class thread_example1 implements Runnable {
    @Override
    public void run() {
    }
    public static void main(String[] args) {
        Thread guruthread1 = new Thread();
        guruthread1.start();
        try {
            guruthread1.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        guruthread1.setPriority(1);
        int gurupriority = guruthread1.getPriority();
        System.out.println(gurupriority);
        System.out.println("Thread Running");
  }
}

Explicación del código:

  • Línea de código 2: Estamos creando una clase "thread_Example1" que implementa la interfaz Runnable (debe ser implementada por cualquier clase cuyas instancias estén destinadas a ser ejecutadas por el hilo).
  • Línea de código 4: Anula el método de ejecución de la interfaz ejecutable, ya que es obligatorio anular ese método.
  • Línea de código 6: Aquí hemos definido el método principal en el que iniciaremos la ejecución del hilo.
  • Línea de código 7: Aquí estamos creando un nuevo nombre de hilo como "guruthread1" al crear una instancia de una nueva clase de hilo.
  • Línea de código 8: Usaremos el método "inicio" del hilo usando la instancia "guruthread1". Aquí el hilo comenzará a ejecutarse.
  • Línea de código 10: Aquí estamos usando el método "dormir" del hilo usando la instancia "guruthread1". Por lo tanto, el hilo dormirá durante 1000 milisegundos.
  • Código 9-14: Aquí hemos puesto el método de suspensión en el bloque try catch ya que se produce una excepción marcada, es decir, una excepción interrumpida.
  • Línea de código 15: Aquí estamos configurando la prioridad del hilo en 1, cualquiera que sea la prioridad que tuviera.
  • Línea de código 16: Aquí obtenemos la prioridad del hilo usando getPriority()
  • Línea de código 17: Aquí estamos imprimiendo el valor obtenido de getPriority
  • Línea de código 18: Aquí estamos escribiendo un texto que el hilo se está ejecutando.

Cuando ejecutas el código anterior, obtienes el siguientewing salida:

Ejemplo de hilo en Java

Salida:

5 es la prioridad del subproceso y el subproceso en ejecución es el texto que es el resultado de nuestro código.

Hilo de Java Synchronización

En subprocesos múltiples, existe la asyncComportamiento cronológico de los programas. Si un hilo escribe algunos datos y otro hilo lee datos al mismo tiempo, puede crear inconsistencia en la aplicación.

Cuando es necesario acceder a los recursos compartidos mediante dos o más subprocesos, entonces syncSe utiliza un enfoque de sincronización.

Java ha proporcionado syncmétodos armonizados para implementar syncComportamiento armonizado.

En este enfoque, una vez que el hilo llega al interior del syncbloque sincronizado, entonces ningún otro hilo puede llamar a ese método en el mismo objeto. Todos los hilos tienen que esperar hasta que ese hilo termine el syncbloque cronizado y sale de ahí.

De esta manera, el syncLa cronización ayuda en una aplicación multiproceso. Un subproceso tiene que esperar hasta que otro subproceso finalice su ejecución solo entonces se permite la ejecución de los otros subprocesos.

Se puede escribir en el siguientewing formar:

Synchronized(object)
{  
        //Block of statements to be synchronized
}

Ejemplo de subprocesos múltiples de Java

En este ejemplo de Java multiproceso, tomaremos dos subprocesos y buscaremos los nombres de los mismos.

Example1:

GuruThread1.java
package demotest;
public class GuruThread1 implements Runnable{

    /**
     * @param args
     */
    public static void main(String[] args) {
        Thread guruThread1 = new Thread("Guru1");
        Thread guruThread2 = new Thread("Guru2");
        guruThread1.start();
        guruThread2.start();
        System.out.println("Thread names are following:");
        System.out.println(guruThread1.getName());
        System.out.println(guruThread2.getName());
    }
    @Override
    public void run() {
    }
}

Explicación del código:

  • Línea de código 3: Hemos tomado una clase "GuruThread1" que implementa Runnable (debe ser implementada por cualquier clase cuyas instancias estén destinadas a ser ejecutadas por el hilo).
  • Línea de código 8: Este es el método principal de la clase.
  • Línea de código 9: Aquí estamos creando una instancia de la clase Thread y creando una instancia denominada "guruThread1" y creando un hilo.
  • Línea de código 10: Aquí estamos creando una instancia de la clase Thread y creando una instancia llamada "guruThread2" y creando un hilo.
  • Línea de código 11: Estamos iniciando el hilo, es decir, guruThread1.
  • Línea de código 12: Estamos iniciando el hilo, es decir, guruThread2.
  • Línea de código 13: Generando el texto como "Los nombres de los hilos son los siguientes".wing: "
  • Línea de código 14: Obtener el nombre del hilo 1 usando el método getName() de la clase de hilo.
  • Línea de código 15: Obtener el nombre del hilo 2 usando el método getName() de la clase de hilo.

Cuando ejecutas el código anterior, obtienes el siguientewing salida:

Ejemplo de subprocesos múltiples de Java

Salida:

Los nombres de los hilos se muestran aquí como

  • Guru1
  • Guru2

Ejemplo 2:

En este ejemplo de subprocesos múltiples en Java, aprenderemos cómo anular los métodos run() y start() de una interfaz ejecutable y crearemos dos subprocesos de esa clase y los ejecutaremos en consecuencia.

Además, estamos tomando dos clases,

  • Uno que implementará la interfaz ejecutable y
  • Otro que tendrá el método principal y se ejecutará en consecuencia.
package demotest;
public class GuruThread2 {
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GuruThread3 threadguru1 = new GuruThread3("guru1");
  threadguru1.start();
  GuruThread3 threadguru2 = new GuruThread3("guru2");
  threadguru2.start();
 }
}
class GuruThread3 implements Runnable {
 Thread guruthread;
 private String guruname;
 GuruThread3(String name) {
  guruname = name;
 }
 @Override
 public void run() {
  System.out.println("Thread running" + guruname);
  for (int i = 0; i < 4; i++) {
   System.out.println(i);
   System.out.println(guruname);
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    System.out.println("Thread has been interrupted");
   }
  }
 }
 public void start() {
  System.out.println("Thread started");
  if (guruthread == null) {
   guruthread = new Thread(this, guruname);
   guruthread.start();
  }
 }
}

Explicación del código:

  • Línea de código 2: Aquí estamos tomando una clase "GuruThread2" que tendrá el método principal.
  • Línea de código 4: Aquí estamos tomando un método principal de la clase.
  • Línea de código 6-7: Aquí estamos creando una instancia de la clase GuruThread3 (que se crea en las líneas siguientes del código) como "threadguru1" y estamos iniciando el hilo.
  • Línea de código 8-9: Aquí estamos creando otra instancia de la clase GuruThread3 (que se crea en las líneas siguientes del código) como "threadguru2" y estamos iniciando el hilo.
  • Línea de código 11: Aquí estamos creando una clase "GuruThread3" que implementa la interfaz ejecutable (debe ser implementada por cualquier clase cuyas instancias estén destinadas a ser ejecutadas por el hilo).
  • Línea de código 13-14: Estamos tomando dos variables de clase de las cuales una es del tipo clase hilo y otra de clase cadena.
  • Línea de código 15-18: Estamos anulando el constructor GuruThread3, que toma un argumento como tipo de cadena (que es el nombre del hilo) que se asigna a la variable de clase guruname y, por lo tanto, se almacena el nombre del hilo.
  • Línea de código 20: Aquí estamos anulando el método run() de la interfaz ejecutable.
  • Línea de código 21: Estamos generando el nombre del hilo usando la declaración println.
  • Línea de código 22-31: Aquí estamos usando un bucle for con el contador inicializado a 0, y no debe ser menor que 4 (podemos tomar cualquier número, por lo tanto, aquí el bucle se ejecutará 4 veces) e incrementamos el contador. Estamos imprimiendo el nombre del hilo y también haciendo que el hilo entre en suspensión durante 1000 milisegundos dentro de un bloque try-catch ya que el método de suspensión generó una excepción marcada.
  • Línea de código 33: Aquí anulamos el método de inicio de la interfaz ejecutable.
  • Línea de código 35: Estamos generando el texto "Hilo iniciado".
  • Línea de código 36-40: Aquí estamos tomando una condición if para verificar si la variable de clase guruthread tiene valor o no. Si es nulo, entonces estamos creando una instancia usando una clase de subproceso que toma el nombre como parámetro (el valor se asignó en el constructor). Después de lo cual el hilo se inicia utilizando el método start().

Cuando ejecutas el código anterior obtienes el siguientewing salida:

Ejemplo de subprocesos múltiples en Java

Salida:

Hay dos hilos, por lo tanto, recibimos dos veces el mensaje "Hilo iniciado".

Obtenemos los nombres del hilo tal como los hemos generado.

Entra en el bucle for donde imprimimos el contador y el nombre del hilo y el contador comienza con 0.

El bucle se ejecuta tres veces y entre ellas el hilo permanece inactivo durante 1000 milisegundos.

Por lo tanto, primero obtenemos guru1, luego guru2 y luego nuevamente guru2 porque el hilo duerme aquí durante 1000 milisegundos y luego, a continuación, guru1 y nuevamente guru1, el hilo duerme durante 1000 milisegundos, por lo que obtenemos guru2 y luego guru1.

Resumen

En este tutorial, vimos aplicaciones multiproceso en Java y cómo usar uno o varios subprocesos en Java.

  • Explique el subproceso múltiple en Java: en el subproceso múltiple, los usuarios no están bloqueados ya que los subprocesos son independientes y pueden realizar múltiples operaciones en el momento
  • Varias etapas del ciclo de vida del hilo son,
    • Nuevo
    • Ejecutable
    • Correr
    • Esperando
    • Muertos
  • También aprendimos sobre synchronización entre subprocesos, lo que ayuda a que la aplicación se ejecute sin problemas.
  • La programación multiproceso en Java facilita muchas más tareas de aplicaciones.