Académique Documents
Professionnel Documents
Culture Documents
– Cours 3 –
Chapitre 02 : La programmation concurrente avec les
Threads
L’API Thread en Java
Staff pédagogique
Nom Grade Faculté/Institut Adresse e-mail
Dr. KITOUNI Ilham MC-A Nouvelles technologies ilham.kitouni@univ-constantine2.dz
Dr. MENNOUR Rostom MC-B Nouvelles technologies rostom.mennour@univ-constantine2.dz
Étudiants concernés
Faculté/Institut Département Niveau spécialité
Nouvelles technologies IFA Master 1 RSD
Objectifs du cours 3
Connaitre l’utilité des threads.
Savoir les méthode de créer un thread en java.
Voir quelque méthode utile pour gérer les threads en java.
Commençons par examiner l’exécution d’un seul thread dans l’exemple suivant:
1 public class NotreClasse {
2 public void run () {
3 for ( int I = 0; I < 100; I ++) {
4 System . out . println ( " Hello " ) ;
5 }
6 }
7 }
Dans cet exemple, nous avons une classe appelée NotreClasse. La classe NotreClasse a une seule
méthode publique appelée run () qui écrit simplement une chaı̂ne 100 fois sur la console Java ou sur la
sortie standard. Si nous exécutons ce code à partir d’un programme java, comme indiqué ci-dessous,
il s’exécute dans le thread du programme :
1 public class NotrePgm {
2 public static void main () {
3 NotreClasse nc = new NotreClasse () ;
4 nc . run () ;
5 }
6 }
Si nous instancions un objet NotreClasse et appelons sa méthode run (), rien d’inhabituel ne se pro-
duit. Un objet est créé, sa méthode run () est appelée et le message ”Hello” est imprimé 100 fois.
Tout comme les autres appels de méthode, l’appelant de la méthode run () attend que la méthode run
() se termine avant de continuer.
Que faire si nous voulons que la méthode run () de NotreClasse s’exécute en parallèle avec main () et
d’autres méthodes du programme principal ? Pour ce faire, nous devons modifier la classe NotreClasse
afin qu’elle puisse être exécutée par un nouveau thread. Nous allons donc commencer par faire hériter
NotreClasse de la classe Thread (java.lang.Thread) :
1 public class NotreClasse extends Thread {
2 public void run () {
3 for ( int I = 0; I < 100; I ++) {
4 System . out . println ( " Hello " ) ;
5 }
6 }
7 }
Si nous compilons ce code et l’exécutons avec notre programme principal, tout fonctionne exactement
comme avant: la méthode main () du programme appelle la méthode run () de l’objet NotreClasse
et attend que la méthode run () soit renvoyée avant de continuer. Le fait que cet exemple compile et
s’exécute prouve que la classe Thread existe. Cette classe est notre premier aperçu de l’API de thread
en Java et constitue l’interface de programmation permettant de démarrer et d’arrêter nos propres
threads. Mais nous n’avons pas encore créé de nouveau fil conducteur. nous avons simplement créé
une classe qui a une méthode run (). Pour continuer, modifions notre principal comme ceci :
1 public class NotrePgm {
2 public static void main () {
3 NotreClasse nc = new NotreClasse () ;
4 nc . start () ;
5 }
6 }
Dans cette deuxième version de notre principal, nous n’avons modifié qu’une ligne : l’appel de la
méthode run () est maintenant un appel de la méthode start (). La compilation et l’exécution de ce
code confirment qu’il fonctionne toujours et que l’utilisateur semble s’exécuter exactement de la même
manière que dans l’exemple précédent. Étant donné que la méthode start () ne fait pas partie de la
classe NotreClasse, nous pouvons en conclure que l’implémentation de la méthode start () fait partie
de la classe Thread ou de l’une de ses superclasses. De plus, le principal accomplissant toujours la
même tâche, nous pouvons en conclure que la méthode start () déclenche un appel, directement ou
indirectement, à la méthode run ().
À y regarder de plus près, ce nouveau principal se comporte différemment de la version précédente. S’il
est vrai que la méthode start () appelle finalement la méthode run (), elle le fait dans un autre thread.
La méthode start () est ce qui crée réellement un autre thread de contrôle; Ce nouveau fil, après avoir
traité quelques détails d’initialisation, appelle ensuite la méthode run (). Une fois la méthode run ()
terminée, ce nouveau thread traite également des détails de la terminaison du thread. La méthode
start () du thread d’origine retourne immédiatement. Ainsi, la méthode run () sera exécutée dans
le thread nouvellement formé à peu près au même moment où la méthode start () retourne dans le
premier thread.
Voici les méthodes de la classe Thread dont nous avons discuté jusqu’à présent:
Thread()
Construit un objet thread en utilisant les valeurs par défaut pour toutes les options.
void run ()
La méthode que le thread nouvellement créé va exécuter. Les développeurs doivent remplacer cette
méthode par le code dans lequel ils souhaitent que le nouveau thread s’exécute. nous montrerons un
peu plus loin l’implémentation par défaut de la méthode run (), mais il s’agit essentiellement d’une
méthode vide.
void start ()
Crée un nouveau thread et exécute la méthode run () définie dans cette classe de thread.
Pour réviser, créer un autre thread de contrôle est un processus en deux étapes. Tout d’abord, nous
devons créer le code qui s’exécute dans le nouveau thread en redéfinissant la méthode run () de notre
sous-classe. Ensuite, nous créons l’objet sous-classé actuel à l’aide de son constructeur (qui appelle le
constructeur par défaut de la classe Thread dans ce cas) et commençons l’exécution de sa méthode
run () en appelant la méthode start () de la sous-classe.
spécifié. Cette méthode est statique et est accessible via le nom de la classe Thread. static void sleep
(longues millisecondes, int nanosecondes) : Met le thread en cours d’exécution en veille pour le
nombre spécifié de millisecondes et de nanosecondes. Cette méthode est statique et est accessible via
le nom de la classe Thread.
Reprenons notre thread NotreClasse :
1 public class NotreClasse extends Thread {
2 public void run () {
3 for ( int I = 0; I < 100; I ++) {
4 System . out . println ( " Hello " ) ;
5 try {
6 sleep ( timediff ) ;
7 } catch ( Exception e ) {}
8 }
9 }
10 }
La méthode sleep () fait partie de la classe Thread et fait en sorte que le thread en cours (le thread
ayant effectué l’appel de la méthode sleep ()) s’interrompe pendant le délai spécifié, en millisecondes.
L’instruction try dans l’exemple de code est nécessaire en raison de certaines des exceptions émises
par la méthode sleep ().
Définir un drapeau signifie que mon thread doit vérifier le drapeau périodiquement. N’y a-t-il pas un
moyen plus propre d’arrêter le fil? Et n’y a-t-il pas moyen de terminer le fil immédiatement plutôt
que d’attendre qu’il vérifie un drapeau ? Eh bien oui et non. La classe Thread contient une méthode
stop () qui vous permet d’arrêter un thread immédiatement: peu importe ce que fait le thread, il
sera terminé. Cependant, la méthode stop () est très dangereuse. En Java 2, la méthode stop () est
obsolète. Cependant, les raisons qui l’ont conduit à devenir obsolète existent réellement dans toutes
les versions de Java. Vous devez donc éviter d’utiliser la méthode stop () dans toutes les versions de
Java.
L’interface Runnable contient une seule méthode: la méthode run (). La classe Thread implémente
réellement l’interface Runnable; par conséquent, lorsque vous héritez de la classe Thread, votre
sous-classe implémente également l’interface Runnable. Cependant, dans ce cas, nous souhaitons
implémenter l’interface Runnable sans hériter réellement de la classe Thread. Ceci est réalisé en rem-
plaçant simplement l’expression ”implémente Runnable” par l’expression ”extend Thread”; aucune
autre modification n’est nécessaire à l’étape 1 de notre processus de création de thread :
1 public class NotreClasse implements Runnable {
2 public void run () {
3 for ( int I = 0; I < 100; I ++) {
4 System . out . println ( " Hello , from another thread " ) ;
5 }
6 }
7 }
Comme auparavant, nous devons créer une instance de la classe NotreClasse. Cependant, dans cette
nouvelle version, nous devons également créer un objet thread réel. Nous créons cet objet en passant
notre référence d’objet NotreClasse exécutable au constructeur du thread en utilisant un nouveau
constructeur de la classe Thread :
1 Thread ( Runnable target )
La méthode start () du nouvel objet Thread est appelée pour commencer l’exécution du nouveau
thread de contrôle.