Vous êtes ici :
Accueil Cours Programmations La Programmation Orientée Objet en Java Le Multithreading

La Programmation Orientée Objet en Java : Le Multithreading

Java est un langage de programmation multithread qui signifie que nous pouvons développer un programme multithread utilisant Java. Un programme multithread contient deux parties ou plus pouvant être exécutées simultanément et chaque partie peut gérer une tâche différente tout en optimisant les ressources disponibles, spécialement lorsque votre ordinateur dispose de plusieurs CPU.

Par définition, le multitâche est lorsque plusieurs processus partagent des ressources de traitement communes telles qu'une CPU. Multithreading étend l'idée du multitâche en applications où vous pouvez subdiviser des opérations spécifiques au sein d'une seule application en threads individuelles. Chacun des threads peut être exécuté en parallèle. Le système d'exploitation divise le temps de traitement non seulement parmi les différentes applications, mais aussi parmi chaque thread d'une application.

Multithreading vous permet d'écrire d'une manière où plusieurs activités peuvent se dérouler simultanément dans le même programme.

Cycle de vie d'un thread

Un thread passe différentes étapes de son cycle de vie. Par exemple, un thread est créé, démarré, s'exécute, puis termine. Le schéma suivant montre le cycle de vie complet d'un thread.

Les étapes ci-dessus sont expliquées ici:

  • New (créé): un nouveau thread commence son cycle de vie dans le nouvel état. Il reste dans cet état jusqu'à ce que le programme démarre le thread. Il est également appelé un thread né.
  • Runnable (exécution): après qu'un thread nouvellement créé démarre, le thread devient exécutable. Un thread dans cet état est considéré comme exécutant sa tâche.
  • Waiting (en attente): Parfois, un thread passe vers l'état d'attente pendant que le thread attend un autre thread pour effectuer une tâche. Un thread se transforme en l'état d'exécution uniquement lorsqu'un autre thread signale le thread en attente pour continuer son exécution.
  • Timed waiting (Attente temporisée): un thread exécutable peut être entrer dans un état d'attente programmé pendant un intervalle de temps spécifié. Un thread dans cet état passe de nouveau à l'état exécutable lorsque cet intervalle de temps expire ou lorsque l'événement en attente se produit.
  • Terminated (terminé): un thread exécutable entre dans l'état terminé lorsqu'il termine sa tâche ou se termine autrement.

Priorités des Threads

Chaque thread Java a une priorité qui aide le système d'exploitation à déterminer l'ordre dans lequel les threads sont programmés.

Les priorités du thread Java se situent entre MIN_PRIORITY (une constante de 1) et MAX_PRIORITY (une constante de 10). Par défaut, chaque thread a la priorité NORM_PRIORITY (une constante de 5).

Les threads avec une priorité plus élevée sont plus importants pour un programme et devraient être attribués au processeur avant les threads de priorité inférieure. Cependant, les priorités du thread ne peuvent pas garantir l'ordre dans lequel les threads sont exécutés et beaucoup de dépendant de la plateforme.

Créer un thread en implémentant l'interface Runnable

Si votre classe est destinée à être exécutée en tant que thread, vous pouvez y parvenir en mettant en œuvre l'interface Runnable. Vous devrez suivre trois étapes de base:

Étape 1:

Dans un premier temps, vous devez implémenter la méthode run( ) fournie par l'interface Runnable . Cette méthode fournit un point d'entrée pour le thread et vous mettez le logique métier complet dans cette méthode. Voici une syntaxe simple de la méthode run ( ):

public void run();

Étape 2:

À la deuxième étape, vous créez une instanciation d'un objet Thread en utilisant le constructeur suivant:

Thread(Runnable threadObj, String threadName);

Où, threadObj est une instance d'une classe qui implémente l'interface Runnable et threadName est le nom donné au nouveau thread.

Étape 3

Une fois que l'objet Thread est créé, vous pouvez le démarrer en appelant la méthode start( ), qui fait appel  à  la méthode run(). Voici une simple syntaxe de la méthode start( ):

void start();

Exemple:

Voici un exemple qui crée un nouveau thread et le lance en cours d'exécution:

class RunnableDemo implements Runnable {
   private Thread t;
   private String threadName;
   RunnableDemo( String name){
       threadName = name;
       System.out.println("Creating " +  threadName );
   }
   public void run() {
      System.out.println("Running " +  threadName );
      try {
         for(int i = 4; i > 0; i--) {
            System.out.println("Thread: " + threadName + ", " + i);
            //Let the thread sleep for a while.
            Thread.sleep(50);
         }
     } catch (InterruptedException e) {
         System.out.println("Thread " +  threadName + " interrupted.");
     }
     System.out.println("Thread " +  threadName + " exiting.");
   }
  
   public void start ()
   {
      System.out.println("Starting " +  threadName );
      if (t == null)
      {
         t = new Thread (this, threadName);
         t.start ();
      }
   }

}

public class TestThread {
   public static void main(String args[]) {
  
      RunnableDemo R1 = new RunnableDemo( "Thread-1");
      R1.start();
     
      RunnableDemo R2 = new RunnableDemo( "Thread-2");
      R2.start();
   }  
}

 Cela produirait le résultat suivant:

Creating Thread-1

Starting Thread-1

Creating Thread-2

Starting Thread-2

Running Thread-1

Thread: Thread-1, 4

Running Thread-2

Thread: Thread-2, 4

Thread: Thread-1, 3

Thread: Thread-2, 3

Thread: Thread-1, 2

Thread: Thread-2, 2

Thread: Thread-1, 1

Thread: Thread-2, 1

Thread Thread-1 exiting.

Thread Thread-2 exiting.

Créer un thread en étendant la classe Thread

La deuxième façon de créer un thread consiste à créer une nouvelle classe qui étend la classe Thread en utilisant les deux étapes simples suivantes. Cette approche offre plus de souplesse dans la gestion de plusieurs threads créés en utilisant les méthodes disponibles dans la classe Thread.

Étape 1

Vous devrez redéfinir la méthode run( ) disponible dans la classe Thread. Cette méthode fournit un point d'entrée pour le thread et vous mettez le logique métier complet dans cette méthode. Voici une syntaxe simple de la méthode run ( ):

public void run();

Étape 2

Une fois que l'objet Thread est créé, vous pouvez le démarrer en appelant la méthode start( ), qui fait appel  à  la méthode run(). Voici une simple syntaxe de la méthode start( ):

 void start();

Exemple:

Voici le programme précédent réécrit pour étendre la classe Thread:

class ThreadDemo extends Thread {
   private Thread t;
   private String threadName;

   ThreadDemo( String name){
       threadName = name;
       System.out.println("Creating " +  threadName );
   }

   public void run() {
      System.out.println("Running " +  threadName );
      try {
         for(int i = 4; i > 0; i--) {
            System.out.println("Thread: " + threadName + ", " + i);
            //Let the thread sleep for a while.
            Thread.sleep(50);
         }

     }catch(InterruptedException e) {
         System.out.println("Thread " +  threadName + " interrupted.");
     }

     System.out.println("Thread " +  threadName + " exiting.");
   }

   public void start()
   {
      System.out.println("Starting " +  threadName );
      if(t == null)
      {
         t = new Thread (this, threadName);
         t.start ();
      }
   }
}

public class TestThread{
   public static void main(String args[]) {
      ThreadDemo T1 = new ThreadDemo( "Thread-1");
      T1.start();
      ThreadDemo T2 = new ThreadDemo( "Thread-2");
      T2.start();
   } 
}

Cela produirait le résultat suivant:

Creating Thread-1

Starting Thread-1

Creating Thread-2

Starting Thread-2

Running Thread-1

Thread: Thread-1, 4

Running Thread-2

Thread: Thread-2, 4

Thread: Thread-1, 3

Thread: Thread-2, 3

Thread: Thread-1, 2

Thread: Thread-2, 2

Thread: Thread-1, 1

Thread: Thread-2, 1

Thread Thread-1 exiting.

Thread Thread-2 exiting.

Méthodes de la classe Thread

Voici la liste des méthodes importantes disponibles dans la classe Thread.

SN

Méthodes avec description

1

public void start() 
Démarre le thread dans un fil d'exécution distinct, puis invoque la méthode run() sur cet objet Thread.

2

public void run() 
Si cet objet Thread a été instancié à l'aide d'une cible Runnable distincte, la méthode run() est invoquée sur cet objet Runnable.

3

public final void setName(String name) 
Modifie le nom de l'objet Thread. Il existe également une méthode getName( ) pour récupérer le nom.

4

public final void setPriority(int priority)

Définit la priorité de cet objet Thread. Les valeurs possibles sont comprises entre 1 et 10.

5

public final void setDaemon(boolean on)

Si le paramètre passé est true (vrai) alors ce thread est comme un démon.

6

public final void join(long millisec)
Le thread actuel invoque cette méthode sur un second thread, ce qui fait que le thread actuel se bloque jusqu'à ce que le second thread se termine ou que le nombre spécifié de millisecondes est atteint.

7

public void interrupt()
Interrompt ce thread, ce qui lui permet de continuer l'exécution si elle a été bloquée pour quelque raison que ce soit.

8

public final boolean isAlive()
Renvoie true si le thread est en vie, ce qui est à tout moment après le démarrage du thread mais avant qu'il ne soit terminé.

Les méthodes précédentes sont invoquées sur un objet Thread particulier. Les méthodes suivantes dans la classe Thread sont statiques. L'appel de l'une des méthodes statiques effectue l'opération sur le thread en cours d'exécution.

SN

Méthodes avec description

1

public static void yield()

Cause que le thread en cours d'exécution aboutisse à tous les autres threads de la même priorité qui attendent d'être programmés.

2

public static void sleep(long millisec)
Cause que le thread en cours d'exécution bloque pendant au moins le nombre spécifié de millisecondes.

3

public static boolean holdsLock(Object x)
Renvoie true si le thread actuel contient le verrou sur l'objet donné.

4

public static Thread currentThread()
Renvoie une référence au thread en cours d'exécution, qui est le thread qui invoque cette méthode.

5

public static void dumpStack()
Affiche la trace de la pile pour le thread en cours d'exécution, ce qui est utile lors du débogage d'une application multithread.

Exemple:

Le programme ThreadClassDemo suivant démontre certaines de ces méthodes de la classe Thread. Considérons une classe DisplayMessage qui implémente Runnable :

//File Name : DisplayMessage.java
//Create a thread to implement Runnable
public class DisplayMessage implements Runnable
{
   private String message;
   public DisplayMessage(String message)
   {
      this.message = message;
   }

   public void run()
   {
      while(true)
      {
         System.out.println(message);
      }
   }
}

Voici une autre classe qui étend la classe Thread:

//File Name : GuessANumber.java
//Create a thread to extentd Thread
public class GuessANumber extends Thread
{
   private int number;
   public GuessANumber(int number)
   {
      this.number = number;
   }

   public void run()
   {
      int counter = 0;
      int guess = 0;
      do
      {
          guess = (int) (Math.random() * 100 + 1);
          System.out.println(this.getName() + " guesses " + guess);
          counter++;
      }while(guess != number);
      System.out.println("** Correct! " + this.getName() + " in " + counter + " guesses.**");
   }
}

Voici le programme principal qui utilise les classes définies ci-dessus:

//File Name : ThreadClassDemo.java
public class ThreadClassDemo
{
   public static void main(String [] args)
   {
      Runnable hello = new DisplayMessage("Hello");
      Thread thread1 = new Thread(hello);
      thread1.setDaemon(true);
      thread1.setName("hello");
      System.out.println("Starting hello thread...");
      thread1.start();

      Runnable bye = new DisplayMessage("Goodbye");
      Thread thread2 = new Thread(bye);
      thread2.setPriority(Thread.MIN_PRIORITY);
      thread2.setDaemon(true);
      System.out.println("Starting goodbye thread...");
      thread2.start();
      System.out.println("Starting thread3...");
      Thread thread3 = new GuessANumber(27);
      thread3.start();
      try
      {
         thread3.join();

      }catch(InterruptedException e)
      {
         System.out.println("Thread interrupted.");
      }
      System.out.println("Starting thread4...");
      Thread thread4 = new GuessANumber(75);
      thread4.start();
      System.out.println("main() is ending...");
   }
}

Cela produirait le résultat suivant. Vous pouvez essayer cet exemple encore et encore et vous obtiendrez un résultat différent à chaque fois.

Starting hello thread...

Starting goodbye thread...

Hello

Hello

Hello

Hello

Hello

Hello

Goodbye

Goodbye

Goodbye

Goodbye

Goodbye

.......




Vous êtes ici :
Accueil Cours Programmations La Programmation Orientée Objet en Java Le Multithreading