Java

Notification de cookies

Nous utilisons des cookies pour améliorer votre expérience. En poursuivant votre navigation sur ce site, vous acceptez l'utilisation de cookies. Plus d'informations

Introduction à la programmation concurrente en Java - Multi-threads

Dans le monde informatique, lorsque nous parlons de la concurence(competition), nous nous référons à une série de tâches indépendantes et sans lien qui s'exécutent simultanément sur un ordinateur. Cette concurence peut être réelle si l'ordinateur dispose de plusieurs processeurs ou d'un processeur multi-coeur, ou si l'ordinateur ne dispose que d'un seul processeur central.

Tous les systèmes d'exploitation modernes permettent l'exécution de tâches simultanées. Vous pouvez lire vos courriers électroniques tout en écoutant de la musique ou en lisant des nouvelles sur une page Web. Nous pouvons dire qu'il s'agit d'une concurence au niveau du processus. Mais dans un processus, nous pouvons également avoir plusieurs tâches simultanées. Les tâches simultanées exécutées dans un processus sont appelées threads. Un autre concept lié à la concurrence est le parallélisme.

Il existe différentes définitions et relations avec le concept de concurrence :

  •   Lorsque vous exécutez votre application avec plusieurs threads dans un processeur mono-coeur. Avec cela, vous pouvez voir quand l'exécution de votre programme est apparente.
  •   Vous parlez de parallélisme lorsque vous exécutez votre application avec plusieurs threads dans un processeur multi-coeur ou sur un ordinateur doté de plusieurs processeurs.
  •   Vous parlez de la concurrence lorsque les threads d'une application sont exécutés sans ordre prédéfini et de parallélisme lorsque tous ces threads sont exécutés de manière ordonnée.

Création, exécution et définition des caractéristiques d'un thread 

Comme pour tous les éléments du langage Java, les threads sont des objets.
Nous avons deux façons de créer un thread en Java :

  •  Hériter de la classe Thread et redéfinir la méthode run().
  •   Construire une classe qui implémente l'interface Runnable et la méthode run(), puis créer un objet de la classe Thread en transmettant l'objet Runnable en tant que paramètre, c'est l'approche recommandée qui vous offre plus de flexibilité.

La classe Thread enregistre certains attributs d'informations pouvant nous aider à identifier un thread, à connaître son statut ou à contrôler sa priorité. Ces attributs sont:

  •  ID : cet attribut stocke un identifiant unique pour chaque thread.
  •   Name : cet attribut stocke le nom du thread.
  •   Priority : cet attribut stocke la priorité des objets Thread. Les threads peuvent avoir une priorité comprise entre 1 et 10, 1 étant la priorité la plus basse et 10 la plus élevée. Il n'est pas recommandé de changer la priorité des threads.
  •  Status : cet attribut stocke le statut d'un thread. En Java, un thread peut être présent dans l'un des six états définis dans l'énumération Thread.State: NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING ou TERMINATED. La liste suivante spécifie la signification de chacun de ces états :
    • NEW : le thread a été créé et il n'a pas encore commencé
    • RUNNABLE : le thread est en cours d'exécution dans la machine virtuelle Java
    • BLOCKED : le thread est bloqué et attend un moniteur.
    • WAITING : le thread attend un autre thread
    • TIMED_WAITING : le thread attend un autre thread avec un délai d'attente spécifié
    • TERMINATED : le thread a terminé son exécution
Création de threads en héritant de la classe Thread
Exemple 1 :
                                    class Multithreading extends Thread {
                                        public void run() {
                                            try {
                                                // afficher le thread en cours d'exécution
                                                System.out.println("Thread " + Thread.currentThread().getId() + " est en cours d'exécution");
                                    
                                            } catch (Exception e) {
                                                System.out.println("Exception " + e.getMessage());
                                            }
                                        }
                                    }
                                    
                                    // classe principale
                                    public class Multithread {
                                        public static void main(String[] args) {
                                            int n = 4; // nombre de threads
                                            for (int i = 0; i < n; i++) {
                                                Multithreading object = new Multithreading();
                                                object.start();
                                            }
                                        }
                                    }
                            
Thread 11 est en cours d'exécution
Thread 17 est en cours d'exécution
Thread 16 est en cours d'exécution
Thread 13 est en cours d'exécution
Création de threads en implémentant l'interface Runnable
Exemple 2 :
                                    class Multithreading implements Runnable {
                                        public void run() {
                                            try {
                                                // afficher le thread en cours d'exécution
                                                System.out.println("Thread " + Thread.currentThread().getId() + " est en cours d'exécution");
                                    
                                            } catch (Exception e) {
                                                System.out.println("Exception " + e.getMessage());
                                            }
                                        }
                                    }
                                    
                                    // classe principale
                                    public class Multithread {
                                        public static void main(String[] args) {
                                            int n = 4; // nombre de threads
                                            for (int i = 0; i < n; i++) {
                                                Thread objet = new Thread(new Multithreading());
                                                objet.start();
                                            }
                                        }
                                    }
                            
Thread 16 est en cours d'exécution
Thread 15 est en cours d'exécution
Thread 13 est en cours d'exécution
Thread 14 est en cours d'exécution

Chaque programme Java a au moins un thread d'exécution. Lorsque vous exécutez le programme, JVM exécute le thread d'exécution qui appelle la méthode main() du programme.

Lorsque nous appelons la méthode start() d'un objet Thread, nous créons un autre thread d'exécution. Notre programme aura autant de threads d'exécution que le nombre d'appels passés à la méthode start().

La classe Thread possède des attributs pour stocker toutes les informations d'un thread. Le planificateur de système d'exploitation utilise la priorité des threads pour sélectionner celui qui utilise le processeur à chaque instant et actualise le statut de chaque thread en fonction de sa situation.

Si vous ne spécifiez pas de nom pour un thread, JVM lui attribue automatiquement le nom suivant: Thread-XX, où XX est un nombre. Vous ne pouvez pas modifier l'ID ou le status d'un thread.

Un programme Java se termine à la fin de tous ses threads (plus précisément à la fin de tous ses threads non démons). Si le thread initial (celui qui exécute la méthode main()) se termine, le reste des threads poursuivra leur exécution jusqu'à la fin. Si l'un des threads utilise l'instruction System.exit() pour terminer l'exécution du programme, tous les threads mettront fin à leur exécution respective.

La création d'un objet de la classe Thread ne crée pas de nouveau thread d'exécution. De plus, l'appel de la méthode run() d'une classe qui implémente l'interface Runnable ne crée pas de nouveau thread d'exécution. Ce n'est que lorsque vous appelez la méthode start() qu'un nouveau thread d'exécution est créé.

Classe de Thread vs interface Runnable

  •   Si nous étendons la classe Thread, notre classe ne pourra pas hériter d’une autre classe car Java ne prend pas en charge l’héritage multiple. Toutefois, si nous implémentons l'interface Runnable, notre classe peut toujours hériter de d'autres classes de base.
  •   Nous pouvons obtenir les fonctionnalités de base d'un thread en héritant de la classe Thread, car elle fournit des méthodes intégrées telles que yield(), interrupt(), etc. qui ne sont pas disponibles dans l'interface Runnable.

Partager ce cours avec tes amis :

Rédigé par M. ESSADDOUKI

Learning a new programming language is an easy thing, but the most difficult thing is how to design efficient algorithms for real-world problems, so don't be a programmer, be a problems solver.

Cours Similaires :