Principi base del multithreading

Ottimizzazione del codice in Java

Pavlos Kosmetatos

Lead Engineer @Wealthyhood

Esecuzione sequenziale vs parallela

  • Esecuzione sequenziale -> le operazioni avvengono una dopo l’altra
  • Esecuzione parallela -> più operazioni avvengono in simultanea

Come?

  • Le CPU moderne hanno più core
  • Thread: la più piccola unità di esecuzione
  • Il multithreading distribuisce il lavoro tra i core

Single-threading: una strada a una corsia, le auto si seguono. Multi-threading: più corsie, le auto viaggiano insieme!

Ottimizzazione del codice in Java

Uso dei thread

  • La classe Thread permette di creare nuovi percorsi di esecuzione
  • Ogni Thread può eseguire in modo indipendente
Runnable task = () -> {
    System.out.println("Processing on thread: " + 
                       Thread.currentThread().getName());
};

Thread thread = new Thread(task);
thread.start();
Processing on thread: Thread-0
Ottimizzazione del codice in Java

Lavorare con più thread

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
Ottimizzazione del codice in Java

Stream paralleli

  • Stream: funzione da Java 8+ per semplificare il parallelismo
  • Gestisce automaticamente creazione e gestione dei thread
  • Due modi per crearli:
    • collection.parallelStream()
    • Stream.of(...).parallel()
Ottimizzazione del codice in Java

Esempio di stream paralleli

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

// Sequential processing with stream List<Integer> result2 = numbers.stream() .map(n -> n * 2) .collect(Collectors.toList());
// Parallel processing with parallel stream List<Integer> result3 = numbers.parallelStream() .map(n -> n * 2) .collect(Collectors.toList());
Ottimizzazione del codice in Java

Quando usare il processamento parallelo

  • Operazioni CPU-intensive
  • Elaborazione indipendente dei dati
  • Grandi collezioni di dati
  • Core CPU disponibili > 1
  • L’overhead della parallelizzazione può non valere la pena per:
    • Dataset piccoli
    • Operazioni semplici
Ottimizzazione del codice in Java

Riepilogo

  • Classe Thread per creare percorsi di esecuzione paralleli
  • Stream paralleli per semplificare l’elaborazione di collezioni
  • I benefici dipendono da:
    • Tipo di carico
    • Dimensione dei dati
    • Core disponibili
Ottimizzazione del codice in Java

Passiamo alla pratica !

Ottimizzazione del codice in Java

Preparing Video For Download...