Principes de base du multithreading

Optimiser le code en Java

Pavlos Kosmetatos

Lead Engineer @Wealthyhood

Exécution séquentielle vs parallèle

  • Traitement séquentiel -> les opérations s'exécutent l'une après l'autre
  • Traitement parallèle -> plusieurs opérations s'exécutent en même temps

Comment ?

  • Les CPU modernes ont plusieurs cœurs
  • Fil d'exécution : la plus petite unité d'exécution d'un programme
  • Multithreading : répartit le travail entre ces cœurs

Le monofil est comme une route à une voie : les voitures se suivent. Le multithreading, c'est plusieurs voies où les voitures circulent en parallèle !

Optimiser le code en Java

Utiliser des threads

  • La classe Thread permet de créer de nouveaux chemins d'exécution
  • Chaque Thread peut s'exécuter de façon indépendante
Runnable task = () -> {
    System.out.println("Processing on thread: " + 
                       Thread.currentThread().getName());
};

Thread thread = new Thread(task);
thread.start();
Processing on thread: Thread-0
Optimiser le code en Java

Travailler avec plusieurs threads

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
Optimiser le code en Java

Flux parallèles

  • Flux (streams) – fonctionnalité Java 8+ pour simplifier le parallélisme
  • Gèrent automatiquement la création et la gestion des threads
  • Deux façons de créer :
    • collection.parallelStream()
    • Stream.of(...).parallel()
Optimiser le code en Java

Exemple de flux parallèles

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

// Traitement séquentiel avec stream List<Integer> result2 = numbers.stream() .map(n -> n * 2) .collect(Collectors.toList());
// Traitement parallèle avec parallel stream List<Integer> result3 = numbers.parallelStream() .map(n -> n * 2) .collect(Collectors.toList());
Optimiser le code en Java

Quand utiliser le traitement parallèle

  • Opérations intensives pour le CPU
  • Traitement de données indépendantes
  • Grandes collections de données
  • Cœurs CPU disponibles > 1
  • Le surcoût du parallélisme peut ne pas valoir la peine pour :
    • Petits ensembles de données
    • Opérations simples
Optimiser le code en Java

Résumé

  • Classe Thread pour créer des chemins d'exécution parallèles
  • Flux parallèles pour simplifier le traitement des collections
  • Les gains dépendent de :
    • Type de charge de travail
    • Taille des données
    • Nombre de cœurs disponibles
Optimiser le code en Java

Passons à la pratique !

Optimiser le code en Java

Preparing Video For Download...