Concurrencia y Multihilo en Java: Guía Completa

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course
Here is the translated HTML content from Russian to Spanish, keeping all HTML tags intact and only translating the text content inside tags. ```html

Concurrencia y subprocesamiento múltiple en Java: de la teoría a la práctica



En el mundo moderno del software, el rendimiento de las aplicaciones depende directamente de la capacidad de utilizar eficientemente los recursos del procesador. La concurrencia y el subprocesamiento múltiple en Java son conceptos clave que permiten ejecutar varias tareas simultáneamente, acelerar el procesamiento de datos y crear interfaces de usuario receptivas. En este artículo, analizaremos los mecanismos principales de subprocesamiento múltiple en Java, aprenderemos a crear y gestionar hilos, y también revisaremos las mejores prácticas para evitar errores comunes.



¿Qué es un hilo y cómo crearlo en Java?



Un hilo (thread) es un proceso ligero que se ejecuta dentro de una misma aplicación. Cada hilo tiene su propia pila de llamadas y puede funcionar independientemente de otros hilos. En Java, existen dos formas principales de crear un hilo.



Forma 1: Herencia de la clase Thread

public class MyThread extends Thread {    @Override    public void run() {        System.out.println("¡Hilo " + getName() + " iniciado!");    }

public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); // Inicio del hilo }}


Forma 2: Implementación de la interfaz Runnable

public class MyRunnable implements Runnable {    @Override    public void run() {        System.out.println("Hilo ejecutándose a través de Runnable");    }

public static void main(String[] args) { Thread thread = new Thread(new MyRunnable()); thread.start(); }}


Se recomienda usar la segunda forma, ya que no requiere herencia y permite implementar varias interfaces simultáneamente.



Sincronización de hilos: evitando la condición de carrera



Cuando varios hilos acceden simultáneamente a datos compartidos, se produce una condición de carrera (race condition). Para evitarlo, Java proporciona mecanismos de sincronización.



Palabra clave synchronized

Bloquea el acceso a un método o bloque de código para otros hilos hasta que el hilo actual termine su ejecución:

public class Counter {    private int count = 0;

public synchronized void increment() { count++; }

public synchronized int getCount() { return count; }}


Bloqueos con Lock

Un mecanismo más flexible que synchronized. Permite establecer tiempos de espera e intentar obtener un bloqueo sin bloquearse:

import java.util.concurrent.locks.ReentrantLock;

public class SafeCounter { private final ReentrantLock lock = new ReentrantLock(); private int count = 0;

public void increment() { lock.lock(); try { count++; } finally { lock.unlock(); // Siempre liberamos el bloqueo } }}


Pool de hilos y ExecutorService



Crear un nuevo hilo para cada tarea es una operación costosa. Para una gestión eficiente de los hilos, use ExecutorService del paquete java.util.concurrent.



import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;

public class ThreadPoolExample { public static void main(String[] args) { // Creamos un pool de 4 hilos ExecutorService executor = Executors.newFixedThreadPool(4);

for (int i = 0; i < 10; i++) { final int taskId = i; executor.submit(() -> { System.out.println("Tarea " + taskId + " ejecutándose en " + Thread.currentThread().getName()); }); }

executor.shutdown(); // Finalizamos el pool después de ejecutar todas las tareas }}


Tipos principales de pools: