Le Multithreading en Java

Introduction au Multithreading

Le multithreading est un concept permettant à différentes segments d’un programme de s'exécuter simultanément. Lorsque la partie active d’un programme initie un nouveau fil (ou thread), celui-ci peut exécuter son code en arrière-plan, tandis que le code initial continue à tourner. Cela permet par conséquent d'exécuter des tâches complexes sans bloquer le reste du programme.

Concept de Threads

Les différentes sections d’un programme qui fonctionnent en même temps sont désignées par le terme de "threads". En règle générale, le fil qui démarre ces autres opérations est connu sous le nom de "fil principal". En Java, il existe deux méthodes pour créer des threads : via des classes ou en utilisant des interfaces.

Conditions de Course

Étant donné que Java autorise l'exécution de plusieurs threads simultanément, cela peut engendrer des problèmes de concurrence, appelés conditions de course. Ce phénomène se produit lorsqu'une même variable est accédée et modifiée par plusieurs threads en parallèle, alors qu’ils n’ont pas nécessairement terminé leur exécution. Il est donc conseillé d’éviter de tels éléments, à moins d’être certain que les threads qui peuvent les modifier ont terminé de s’exécuter.

Utilisation de la Classe Thread

Il est possible de définir des threads en créant une classe qui étend la classe Thread et qui redéfinit la méthode .run() :

public class MonThread extends Thread {
  public void run() {
    // Code à exécuter dans le thread séparé
  }
}

Le contenu de la méthode .run() s'exécute dans un thread distinct lorsque ce dernier est initié. Pour démarrer le thread, il suffit de créer une instance de cette classe et d'appeler la méthode .start() :

MonThread thread = new MonThread();
thread.start();

Implémentation de l’Interface Runnable

Une autre méthode pour créer des threads consiste à implémenter l’interface Runnable :

public class MonRunnable implements Runnable {
  public void run() {
    // Code à exécuter dans le thread séparé
  }
}

Dans ce cas, le code de la méthode .run() s'exécute également dans un thread distinct. Pour démarrer ce thread, on crée une instance de cette classe que l'on passe au constructeur de la classe Thread, puis on appelle la méthode .start() :

MonRunnable runnable = new MonRunnable();
Thread thread = new Thread(runnable);
thread.start();

Exemple de Multithreading

Prenons un exemple où des messages sont affichés tant par le fil principal que par un thread distinct :

public class Exemple extends Thread {
  public static void main(String[] args) {
    Exemple thread = new Exemple();
    System.out.println("Ceci est le fil principal.");
    thread.start();
    System.out.println("Ceci est le fil principal.");
  }

  public void run() {
    System.out.println("Ceci est un fil séparé.");
    System.out.println("Ceci est un fil séparé.");
  }
}

L'exécution de ce code pourrait produire un résultat similaire à :

Ceci est le fil principal.
Ceci est le fil principal.
Ceci est un fil séparé.
Ceci est un fil séparé.