Java - Création d'un Thread

Salut à toi, futurs magiciens de Java ! Aujourd'hui, nous allons plonger dans le monde passionnant des threads Java. Ne t'inquiète pas si tu es nouveau dans la programmation ; je vais te guider à travers ce périple étape par étape, comme j'ai fait pour des centaines d'étudiants au fil des ans. Alors, prends ta boisson favorite, installe-toi confortablement, et embarquons ensemble dans cette aventure des threads !

Java - Creating a Thread

Qu'est-ce qu'un Thread ?

Avant de sauter dans la création de threads, comprenons ce qu'est vraiment un thread. Imagine que tu es dans une cuisine, en train de préparer un délicieux repas. Tu coupes des légumes, tu remues la sauce, et tu regardes le four, tout en même temps. Chacune de ces tâches est comme un thread dans un programme informatique - ce sont des tâches distinctes qui peuvent s'exécuter simultanément.

En Java, un thread est l'unité d'exécution la plus petite au sein d'un programme. Il permet à différentes parties de ton programme de s'exécuter simultanément, rendant tes applications plus efficaces et réactives.

Pourquoi utiliser des Threads ?

Tu te demandes peut-être, "Pourquoi me soucier des threads ?" Eh bien, laisse-moi te raconter une petite histoire. Il y a quelques années, je développais une application simple de traitement d'images pour un club de photographie. L'application fonctionnait bien pour de petites images, mais lorsque les utilisateurs tentaient de traiter de grandes photos à haute résolution, elle se bloquait. Le coupable ? Tout se déroulait sur un seul thread ! En implémentant le multi-threading, nous avons pu traiter les images en arrière-plan tout en conservant l'interface utilisateur réactive. Les membres du club de photographie étaient ravis, et j'ai appris une leçon précieuse sur le pouvoir des threads.

Création d'un Thread en Java

En Java, il y a deux principales méthodes pour créer un thread :

  1. Implémenter l'interface Runnable
  2. Étendre la classe Thread

Explorons这两种方法 avec des exemples pratiques !

Méthode 1 : Implémenter l'interface Runnable

Cette méthode est souvent considérée comme la meilleure manière de créer un thread car elle ne nécessite pas que tu sous-classes Thread, ce qui permet à ta classe de hériter d'autres classes si nécessaire.

Voici un exemple simple :

public class MonRunnable implements Runnable {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread utilisant Runnable: " + i);
try {
Thread.sleep(1000); // Pause de 1 seconde
} catch (InterruptedException e) {
System.out.println("Thread interrompu.");
}
}
}

public static void main(String[] args) {
MonRunnable monRunnable = new MonRunnable();
Thread thread = new Thread(monRunnable);
thread.start();

// Thread principal
for (int i = 1; i <= 5; i++) {
System.out.println("Thread principal: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Thread principal interrompu.");
}
}
}
}

Reprenons cela :

  1. Nous créons une classe MonRunnable qui implémente l'interface Runnable.
  2. Nous surchargeons la méthode run(), qui définit ce que le thread fera lorsqu'il est démarré.
  3. Dans la méthode main, nous créons une instance de MonRunnable et la passons à un nouvel objet Thread.
  4. Nous appelons start() sur le thread pour commencer son exécution.
  5. Le thread principal imprime également des nombres, montrant comment les deux threads s'exécutent concurremment.

Lorsque vous exécutez ce programme, vous verrez les nombres des deux threads entrelacés, montrant qu'ils s'exécutent simultanément !

Méthode 2 : Étendre la classe Thread

Cette méthode consiste à créer une sous-classe de Thread et à surcharger sa méthode run(). Voici un exemple :

public class MonThread extends Thread {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("Thread étendant la classe Thread: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Thread interrompu.");
}
}
}

public static void main(String[] args) {
MonThread monThread = new MonThread();
monThread.start();

// Thread principal
for (int i = 1; i <= 5; i++) {
System.out.println("Thread principal: " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Thread principal interrompu.");
}
}
}
}

Les différences clés ici sont :

  1. Notre classe MonThread étend Thread au lieu d'implémenter Runnable.
  2. Nous pouvons appeler directement start() sur notre objet MonThread, sans avoir besoin de créer une instance séparée de Thread.

Comparaison des Deux Méthodes

Les deux méthodes atteignent le même résultat, mais il y a quelques considérations :

Fonctionnalité Interface Runnable Étendre la classe Thread
Flexibilité Peut hériter d'autres classes Ne peut pas hériter d'autres classes (Java ne supporte pas l'héritage multiple)
Séparation des préoccupations Sépare la tâche du thread Combine la tâche et le thread dans une seule classe
Réutilisabilité Plus réutilisable Moins réutilisable
Éfficacité des ressources Plus efficace (peut être utilisé avec des pools de threads) Moins efficace

Dans la plupart des cas, implémenter Runnable est considérée comme une meilleure pratique car elle offre plus de flexibilité et s'aligne mieux avec les principes de conception orientée objet.

Conclusion

Félicitations ! Tu viens de faire tes premiers pas dans le monde du threading Java. Nous avons couvert les bases de ce qu'est un thread, pourquoi ils sont utiles, et comment les créer en utilisant deux méthodes différentes. Souviens-toi, comme apprendre à jongler, maîtriser les threads nécessite de la pratique. Ne sois pas découragé si cela ne fonctionne pas immédiatement - continue d'expérimenter et tu y parviendras !

Dans ma prochaine leçon, nous plongerons plus profondément dans la synchronisation des threads et la communication entre threads. Jusque-là, bon codage, et que tes threads s'exécutent toujours en douceur !

Credits: Image by storyset