Prioridad de Hilos en Java

Avanzado

Cada hilo tiene asociada una configuración de prioridad. La prioridad de un hilo determina, en parte, cuánto tiempo de CPU recibe un hilo en relación con los otros hilos activos.

1. Introducción a Prioridades

En general, durante un período de tiempo determinado, los hilos de baja prioridad reciben poco. Los hilos de alta prioridad reciben mucho. Como era de esperar, la cantidad de tiempo de CPU que recibe un hilo tiene un profundo impacto en sus características de ejecución y su interacción con otros hilos que se están ejecutando actualmente en el sistema.

Es importante comprender que factores distintos de la prioridad de un hilo también afectan la cantidad de tiempo de CPU que recibe un hilo. Por ejemplo, si un hilo de alta prioridad está esperando algún recurso, quizás para la entrada del teclado, se bloqueará y se ejecutará un hilo de menor prioridad. Sin embargo, cuando ese hilo de alta prioridad obtiene acceso al recurso, puede adelantarse al hilo de baja prioridad y reanudar la ejecución.

Otro factor que afecta la programación de los hilos es la forma en que el sistema operativo implementa la multitarea. Por lo tanto, solo porque le dé a un hilo una prioridad alta y a otro una prioridad baja no significa necesariamente que un hilo se ejecutará más rápido o más a menudo que el otro. Es solo que el hilo de alta prioridad tiene un mayor acceso potencial a la CPU.

2. Asignar prioridades a hilos

Cuando se inicia un hilo secundario, su configuración de prioridad es igual a la de su hilo principal. Puede cambiar la prioridad de un hilo llamando a setPriority(), que es un miembro de Thread. Esta es su forma general:

final void setPriority(int nivel)
El método java.lang.Thread.setPriority() cambia la prioridad del hilo al valor nivel. Este método arroja IllegalArgumentException si el valor del parámetro nivel va más allá del límite mínimo (1) y máximo (10).

Aquí, el nivel especifica la nueva configuración de prioridad para el hilo de llamada. El valor del nivel debe estar dentro del rango MIN_PRIORITY y MAX_PRIORITY. Actualmente, estos valores son 1 y 10, respectivamente. Para devolver un hilo a la prioridad predeterminada, especifique NORM_PRIORITY, que actualmente es 5. Estas prioridades se definen como variables finales estáticas dentro de Thread.

  • public static int MIN_PRIORITY: esta es la prioridad mínima que un hilo puede tener. El valor es 1.
  • public static int NORM_PRIORITY: esta es la prioridad predeterminada de un hilo si no lo define explícitamente. El valor es 5.
  • public static int MAX_PRIORITY: esta es la prioridad máxima de un hilo. El valor es 10.

Puede obtener la configuración de prioridad actual llamando al método getPriority() de Thread, que se muestra aquí:

final int getPriority()
El método java.lang.Thread.getPriority() devuelve la prioridad del hilo dado.

3. Ejemplo con getPriority en Java

class DemoPrioridadGet extends Thread
{
    public void run()
    {
        System.out.println("Dentro del método run");
    }

    public static void main(String[]args)
    {
        DemoPrioridadGet t1 = new DemoPrioridadGet();
        DemoPrioridadGet t2 = new DemoPrioridadGet();
        DemoPrioridadGet t3 = new DemoPrioridadGet();

        System.out.println("Prioridad del hilo t1 : " +
                t1.getPriority()); // Por defecto 5
        System.out.println("Prioridad del hilo t2 : " +
                t2.getPriority()); // Por defecto 5
        System.out.println("Prioridad del hilo t3 : " +
                t3.getPriority()); // Por defecto 5

        t1.setPriority(2);
        t2.setPriority(5);
        t3.setPriority(8);

        // t3.setPriority(21); arrojará IllegalArgumentException
        System.out.println("Prioridad del hilo t1 : " +
                t1.getPriority());  //2
        System.out.println("Prioridad del hilo t2 : " +
                t2.getPriority()); //5
        System.out.println("Prioridad del hilo t3 : " +
                t3.getPriority());//8

        // Hilo Principal (Main thread)
        System.out.print(Thread.currentThread().getName()+": ");
        System.out.println("Prioridad del hilo Main : "
                + Thread.currentThread().getPriority());

        // La prioridad del hilo principal se establece en 10
        Thread.currentThread().setPriority(10);
        System.out.println("Prioridad del hilo Main : "
                + Thread.currentThread().getPriority());
    }
}

Salida:

Prioridad del hilo t1 : 5
Prioridad del hilo t2 : 5
Prioridad del hilo t3 : 5
Prioridad del hilo t1 : 2
Prioridad del hilo t2 : 5
Prioridad del hilo t3 : 8
main: Prioridad del hilo Main : 5
Prioridad del hilo Main : 10
  • El hilo con la prioridad más alta tendrá probabilidad de ejecución antes que otros hilos. Supongamos que hay 3 hilos t1, t2 y t3 con prioridades 4, 6 y 1. Por lo tanto, el hilo t2 se ejecutará primero según la prioridad máxima de 6, después t1 se ejecutará y luego t3.
  • La prioridad predeterminada para el hilo principal es siempre 5, se puede cambiar más tarde. La prioridad predeterminada para todos los demás hilos depende de la prioridad del hilo principal.
  • Si dos hilos tienen la misma prioridad, entonces no podemos esperar qué hilo se ejecutará primero. Depende del algoritmo del planificador de hilos (Round-Robin, First Come First Serve, etc.)

4. Ejemplo con setPriority en Java

El siguiente ejemplo muestra los hilos en diferentes prioridades. Los hilos se crean como instancias de Priority.

//Demostración de prioridades en hilos
class PrioridadHilos implements Runnable {
    int contar;
    Thread hilo;

    static boolean stop=false;
    static String actualNombre;

    //Construye un nuevo hilo.
    PrioridadHilos(String nombre){
        hilo= new Thread(this,nombre);
        contar=0;
        actualNombre=nombre;
    }

    //Punto de entrada de hilo.
    public void run(){
        System.out.println(hilo.getName()+" iniciando.");
        do {
            contar++;
            if (actualNombre.compareTo(hilo.getName())!=0){
                actualNombre=hilo.getName();
                System.out.println("En "+actualNombre);
            }
        }while (stop==false&&contar<10000000);
        stop=true;
        System.out.println("\n"+ hilo.getName()+" terminado.");
    }
}
class DemoPrioridad{
    public static void main(String[] args) {
    PrioridadHilos ph1= new PrioridadHilos("Prioridad Alta");
    PrioridadHilos ph2= new PrioridadHilos("Prioridad Baja");
    PrioridadHilos ph3= new PrioridadHilos("Prioridad Normal #1");
    PrioridadHilos ph4= new PrioridadHilos("Prioridad Normal #2");
    PrioridadHilos ph5= new PrioridadHilos("Prioridad Normal #3");

    //Establecer prioridades
        ph1.hilo.setPriority(Thread.NORM_PRIORITY+2);
        ph2.hilo.setPriority(Thread.NORM_PRIORITY-2);
     //Deje ph3, ph4 y ph5 en el nivel de prioridad normal predeterminado

     //Comenzar los hilos
        ph1.hilo.start();
        ph2.hilo.start();
        ph3.hilo.start();
        ph4.hilo.start();
        ph5.hilo.start();
    try {
        ph1.hilo.join();
        ph2.hilo.join();
        ph3.hilo.join();
        ph4.hilo.join();
        ph5.hilo.join();
    }catch (InterruptedException exc){
        System.out.println("Hilo principal interrumpido.");
    }
        System.out.println("\nHilo de alta prioridad contó hasta "+ph1.contar);
        System.out.println("Hilo de baja prioridad contó hasta "+ph2.contar);
        System.out.println("Hilo de normal prioridad #1 contó hasta "+ph3.contar);
        System.out.println("Hilo de normal prioridad #2 contó hasta "+ph4.contar);
        System.out.println("Hilo de normal prioridad #3 contó hasta "+ph5.contar);
    }
}
  • El método run() contiene un bucle que cuenta el número de iteraciones.
  • El ciclo se detiene cuando el conteo llega a 10,000,000 o la variable estática stop es true. Inicialmente, stop se establece en false, pero el primer hilo para finalizar los conjuntos de conteo establece stop en true. Esto provoca que cada hilo termine con su siguiente segmento de tiempo.
  • Cada vez que se pasa por el ciclo, la cadena nombreActual se compara con el nombre del hilo que se está ejecutando. Si no coinciden, significa que se produjo un cambio de tarea. Cada vez que se produce un cambio de tarea, se muestra el nombre del nuevo hilo y se le asigna al nombreActual el nombre del nuevo hilo.
  • La visualización de cada cambio de hilo le permite ver (de forma muy imprecisa) cuando los hilos obtienen acceso a la CPU. Después de detener los hilos, se muestra el número de iteraciones para cada ciclo.

Salida:

Hilo de alta prioridad contó hasta 10000000
Hilo de baja prioridad contó hasta 729262
Hilo de normal prioridad #1 contó hasta 9563850
Hilo de normal prioridad #2 contó hasta 4784722
Hilo de normal prioridad #3 contó hasta 9983470

En esta ejecución, el hilo de alta prioridad obtuvo la mayor cantidad de tiempo de CPU. Por supuesto, la salida exacta producida por este programa dependerá de una serie de factores, incluida la velocidad de tu CPU, la cantidad de CPU en tu sistema, el sistema operativo que está utilizando y el número y la naturaleza de otras tareas que se ejecutan en el sistema. Por lo tanto, es posible que el hilo de baja prioridad obtenga el mayor tiempo de CPU si las circunstancias son las correctas.

Hilos en Java
  • Prioridades de Hilos

Sobre el Autor:

Hey hola! Yo soy Alex Walton y tengo el placer de compartir conocimientos hacía ti sobre el tema de Programación en Java, desde cero, Online y Gratis.

Deja una Respuesta

*

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.