Principios básicos de multihilo

Optimizing Code in Java

Pavlos Kosmetatos

Lead Engineer @Wealthyhood

Ejecución secuencial vs. paralela

  • Procesamiento secuencial -> las operaciones ocurren una tras otra
  • Procesamiento en paralelo -> varias operaciones ocurren a la vez

¿Cómo?

  • Las CPU modernas tienen varios núcleos
  • Hilo: la unidad más pequeña de ejecución de un programa
  • Multihilo reparte el trabajo entre estos núcleos

El monohilo es como una carretera de un solo carril donde los coches van en fila. El multihilo es como tener varios carriles por los que pueden circular a la vez.

Optimizing Code in Java

Uso de hilos

  • La clase Thread permite crear nuevas rutas de ejecución
  • Cada Thread puede ejecutarse de forma independiente
Runnable task = () -> {
    System.out.println("Processing on thread: " + 
                       Thread.currentThread().getName());
};

Thread thread = new Thread(task);
thread.start();
Processing on thread: Thread-0
Optimizing Code in Java

Trabajar con varios hilos

List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 4; i++) {
    Thread thread = new Thread(() -> System.out.println("Processing data on Thread-" + i));
    threads.add(thread);
    thread.start();
}

for (Thread t : threads) {
    t.join(); // Waits for all threads to complete
}
// Processing data on Thread-0
// Processing data on Thread-2
// Processing data on Thread-1
// Processing data on Thread-3
Optimizing Code in Java

Streams paralelos

  • Streams: función de Java 8+ para paralelismo simplificado
  • Gestiona automáticamente la creación y administración de hilos
  • Dos formas de crearlos:
    • collection.parallelStream()
    • Stream.of(...).parallel()
Optimizing Code in Java

Ejemplo de streams paralelos

// Procesamiento secuencial
List<Integer> result1 = new ArrayList<>();
for (int i = 0; i < numbers.size(); i++) {
    result1.add(numbers.get(i) * 2);
}

// Procesamiento secuencial con stream List<Integer> result2 = numbers.stream() .map(n -> n * 2) .collect(Collectors.toList());
// Procesamiento en paralelo con parallel stream List<Integer> result3 = numbers.parallelStream() .map(n -> n * 2) .collect(Collectors.toList());
Optimizing Code in Java

Cuándo usar procesamiento paralelo

  • Operaciones intensivas de CPU
  • Procesamiento de datos independiente
  • Colecciones de datos grandes
  • Núcleos de CPU disponibles > 1
  • La sobrecarga de paralelizar puede no compensar si:
    • Conjuntos de datos pequeños
    • Operaciones simples
Optimizing Code in Java

Resumen

  • Clase Thread para crear rutas de ejecución en paralelo
  • Streams paralelos para simplificar el procesamiento de colecciones
  • Los beneficios dependen de:
    • Tipo de carga de trabajo
    • Tamaño de los datos
    • Núcleos disponibles
Optimizing Code in Java

¡Vamos a practicar!

Optimizing Code in Java

Preparing Video For Download...