Programación asíncrona en Java: guía completa con ejemplos

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

Introducción a la programación asíncrona en Java



La programación asíncrona es un paradigma de desarrollo en el que la ejecución de operaciones largas (como solicitudes de red, lectura de archivos o cálculos) no bloquea el hilo principal de la aplicación. En Java, este concepto ha recorrido un largo camino de evolución: desde hilos básicos (Thread) hasta potentes abstracciones como CompletableFuture y flujos reactivos.



En el desarrollo moderno, la asincronía es fundamental para crear servidores web receptivos, microservicios de alta carga y procesadores de datos eficientes. Esta guía te ayudará a dominar todos los aspectos clave de la programación asíncrona en Java, desde lo básico hasta técnicas avanzadas.



Fundamentos: hilos y ExecutorService



El problema de las operaciones bloqueantes



El código síncrono tradicional bloquea el hilo hasta que la operación se completa. Por ejemplo, al ejecutar una solicitud HTTP:



public String fetchData() throws InterruptedException {    Thread.sleep(2000); // Simulación de una solicitud larga    return "Datos obtenidos";}


Mientras el método fetchData() se ejecuta, el hilo no puede procesar otras solicitudes. En aplicaciones multihilo, esto conduce a un uso ineficiente de los recursos.



ExecutorService — gestión del pool de hilos



Java proporciona ExecutorService para gestionar un pool de hilos. En lugar de crear nuevos hilos manualmente, usas un pool listo:



import java.util.concurrent.*;

public class ExecutorExample { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService executor = Executors.newFixedThreadPool(4); Future<String> future = executor.submit(() -> { Thread.sleep(2000); return "Resultado del cálculo"; }); System.out.println("Esperando el resultado..."); String result = future.get(); // Bloquea el hilo hasta obtener el resultado System.out.println("Recibido: " + result); executor.shutdown(); }}


Importante: Future.get() es una operación bloqueante. Para una verdadera asincronía se necesitan herramientas más avanzadas.



CompletableFuture: asincronía potente



A partir de Java 8, CompletableFuture se convirtió en la herramienta principal para la programación asíncrona. Permite crear cadenas de operaciones asíncronas sin bloquear hilos.



Creación y operaciones básicas



import java.util.concurrent.CompletableFuture;import java.util.concurrent.ExecutionException;

public class CompletableFutureExample { public static void main(String[] args) throws ExecutionException, InterruptedException { // Ejecución asíncrona CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return "Resultado asíncrono"; }); // Procesamiento no bloqueante del resultado future.thenAccept(result -> System.out.println("Procesado: " + result)); System.out.println("El hilo principal continúa trabajando..."); // Bloqueo para finalizar el programa future.get(); }}


Cadenas y combinaciones



Una de las principales ventajas de CompletableFuture es la capacidad de construir cadenas complejas de operaciones asíncronas:



public class AsyncChainExample {    public static void main(String[] args) throws ExecutionException, InterruptedException {        CompletableFuture.supplyAsync(() -> {            System.out.println("Paso 1: Obteniendo datos");            return "user_123";        })        .thenApp                

Blogs

Book Recommendations